home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d2 / rnco_mod.arc / CO.ASM next >
Encoding:
Assembly Source File  |  1988-04-28  |  158.4 KB  |  3,805 lines

  1. ; Co.asm
  2. ;COPYRIGHT      DB     10,"CO 1.0 (c) 1987 Ziff Communications Co.",13, 10
  3. ;PROGRAMMER     DB     26,"Michael J. Mefford" SET_ENV_LGTH   DB  0
  4. ; Format       CO [d:][directory]
  5. ;
  6. ;Michael J. Mefford    1987/No. 21 (Utilities)
  7. ;
  8. ;This is a modified version of PC Magazines CO Utility
  9. ;It has Been modified for some special batch tasks.
  10. ;Several new parameters have been added.
  11. ;
  12. ;Purpose:
  13. ;Select, Copy, move, or delete file(s) individually or in tagged
  14. ;groups from directory listings sorted by name, extension, size, or date.
  15. ;
  16. ;One special function will place the file name selected in the
  17. ;environment variable FILE=name. You may view it with the set command.
  18. ;
  19. ;Format:
  20. ;CO [d:][\directory 1] [d:][\directory 2] [/E][/S][/D][/T][/O]
  21. ;                                         [/M3] [/M4]
  22. ;
  23. ;Directory 1 - CO will read and display files in this directory
  24. ;Directory 2 - CO will only copy to this direcory when this parameter
  25. ;              is entered.
  26. ;
  27. ;/E          - Sort Files by file extension.
  28. ;/S          - Sort Files by file size.
  29. ;/D          - Sort Files by Date and time.
  30. ;/T          - Sort Files by Date and time.
  31. ;/O          - Don't Sort Files leave in order DOS put them.
  32. ;/M3         - Special setup for copying models to start a program
  33. ;/M4         - Start with Long menu (RN call with this parm).
  34. ;
  35. ;Program Functions:
  36. ;
  37. ;         ╔═════════════════════════════╗
  38. ;         ║     PC Magazine CO.COM      ║
  39. ;         ╟─────────────────────────────╢
  40. ;         ║ Enter ─┘ Select & End Pgm  ║
  41. ;         ║                             ║
  42. ;         ║ F3  ^Sort directory names   ║
  43. ;         ║ F4  ^Browse selected file   ║
  44. ;         ║ F5  ^Rename File(s)         ║
  45. ;         ║ F6  ^Delete File(s)         ║
  46. ;         ║ F7  ^Copy File(s)           ║
  47. ;         ║ F8  ^Move File(s)           ║
  48. ;         ║ F9   Mark all files         ║
  49. ;         ║ F10  Clear all marked Files ║
  50. ;         ║       Toggles (on/off)      ║
  51. ;         ║ √^Verify  ^EBCDIC  ^Wordstar║
  52. ;         ║ +/- Ins/Del to Mark/Unmark  ║
  53. ;         ║ Esc to Cancel Program       ║
  54. ;         ╚═════════════════════════════╝
  55. ;               Use:   PgUp PgDn
  56. ;              ^PgUp ^PgDn Home End
  57. ;
  58. ;
  59. ;Modified by Bob Hunt 414-287-3308
  60.  
  61. CODE SEGMENT                           ;********************************;
  62. ASSUME CS:CODE,DS:CODE                 ;*                              *;
  63. ORG 100H                               ;*  Requires MASM 2.0 or later  *;
  64.                                        ;*     Remember to EXE2BIN      *;
  65. START:         JMP    BEGINNING        ;*                              *;
  66.                                        ;********************************;
  67.  
  68. ;
  69. ;           DATA AREA
  70.  
  71. ;               PC         HOST
  72. ;               ---------- --------
  73. EBCDIC_TR  DB  000H ;nul   00 . nul
  74.            DB  001H ;soh . 01 . soh
  75.            DB  002H ;stx . 02 . stx
  76.            DB  003H ;etx . 03 . etx
  77.            DB  004H ;eot . 04 . sel
  78.            DB  009H ;ht  . 05 . ht
  79.            DB  006H ;ack . 06 . rnl
  80.            DB  07FH ;del . 07 . del
  81.            DB  008H ;bs    08 . ge
  82.            DB  009H ;ht    09 . sps
  83.            DB  00AH ;lf    0A . rpt
  84.            DB  00BH ;vt    0B . vt
  85.            DB  00CH ;ff    0C . ff
  86.            DB  00DH ;cr    0D . cr
  87.            DB  00EH ;so    0E . so
  88.            DB  00FH ;si    0F . si
  89.            DB  010H ;dle   10 . dle
  90.            DB  011H ;dc1   11 . dc1
  91.            DB  012H ;dc2   12 . dc2
  92.            DB  013H ;dc3   13 . dc3
  93.            DB  014H ;dc4   14 . res/enp
  94.            DB  015H ;nak . 15 . nl
  95.            DB  008H ;bs    16 . bs
  96.            DB  017H ;etb . 17 . poc
  97.            DB  018H ;can . 18 . can
  98.            DB  019H ;em  . 19 . em
  99.            DB  01AH ;sub   1A . ubs
  100.            DB  01BH ;esc   1B . cu1
  101.            DB  01CH ;fs    1C . ifs
  102.            DB  01DH ;gs  . 1D . igs
  103.            DB  01EH ;rs  . 1E . irs
  104.            DB  01FH ;us  . 1F . itb/ius
  105.            DB  020H ;sp    20 . ds
  106.            DB  021H ;    ! 21 . sos
  107.            DB  01CH ;fs    22 . fs
  108.            DB  023H ;    # 23 . wus
  109.            DB  024H ;    $ 24 . byp/inp
  110.            DB  00AH ;lf    25 . lf
  111.            DB  017H ;etb . 26 . etb
  112.            DB  01BH ;esc   27 . esc
  113.            DB  028H ;    ( 28 . sa
  114.            DB  029H ;    ) 29 . sfe
  115.            DB  02AH ;    * 2A . sm/sw
  116.            DB  02BH ;    + 2B . csp
  117.            DB  02CH ;    , 2C . mfa
  118.            DB  005H ;    - 2D . enq
  119.            DB  006H ;ack . 2E . ack
  120.            DB  007H ;bel   2F . bel
  121. ;
  122. ;               PC         HOST
  123. ;               ---------- --------
  124.            DB  030H ;    0 30 .
  125.            DB  031H ;    1 31 .
  126.            DB  016H ;syn . 32 . syn
  127.            DB  033H ;    3 33 . ir
  128.            DB  034H ;    4 34 . pp
  129.            DB  01EH ;rs  . 35 . trn
  130.            DB  036H ;    6 36 . nbs
  131.            DB  004H ;eot . 37 . eot
  132.            DB  038H ;    8 38 . sbs
  133.            DB  039H ;    9 39 . it
  134.            DB  03AH ;    : 3A . rff
  135.            DB  03BH ;    ; 3B . cu3
  136.            DB  014H ;dc4   3C . dc4
  137.            DB  015H ;nak . 3D . nak
  138.            DB  03EH ;    > 3E .
  139.            DB  01AH ;sub   3F . sub
  140.            DB  020H ;sp    40   sp
  141.            DB  041H ;    A 41
  142.            DB  042H ;    B 42
  143.            DB  043H ;    C 43
  144.            DB  044H ;    D 44
  145.            DB  045H ;    E 45
  146.            DB  046H ;    F 46
  147.            DB  047H ;    G 47
  148.            DB  048H ;    H 48
  149.            DB  049H ;    I 49
  150.            DB  09BH ;      4A
  151.            DB  02EH ;    . 4B .
  152.            DB  03CH ;    < 4C <
  153.            DB  028H ;    ( 4D (
  154.            DB  02BH ;    + 4E +
  155.            DB  0B3H ;    . 4F .
  156.            DB  026H ;    & 50 &
  157.            DB  051H ;    Q 51
  158.            DB  052H ;    R 52
  159.            DB  053H ;    S 53
  160.            DB  054H ;    T 54
  161.            DB  055H ;    U 55
  162.            DB  056H ;    V 56
  163.            DB  057H ;    W 57
  164.            DB  058H ;    X 58
  165.            DB  059H ;    Y 59
  166.            DB  021H ;    ! 5A !
  167.            DB  024H ;    $ 5B $
  168.            DB  02AH ;    * 5C *
  169.            DB  029H ;    ) 5D )
  170.            DB  03BH ;    ; 5E ;
  171.            DB  05EH ;    ^ 5F ^
  172. ;
  173. ;
  174. ;               PC        HOST
  175.  
  176. ;             -------- --------
  177.            DB  02DH ;    - 60 -
  178.            DB  02FH ;    / 61 /
  179.            DB  062H ;    b 62
  180.            DB  063H ;    c 63
  181.            DB  064H ;    d 64
  182.            DB  065H ;    e 65
  183.            DB  066H ;    f 66
  184.            DB  067H ;    g 67
  185.            DB  068H ;    h 68
  186.            DB  069H ;    i 69
  187.            DB  07CH ;    | 6A |
  188.            DB  02CH ;    , 6B ,
  189.            DB  025H ;    % 6C %
  190.            DB  05FH ;    _ 6D _
  191.            DB  03EH ;    > 6E >
  192.            DB  03FH ;    ? 6F ?
  193.            DB  070H ;    p 70
  194.            DB  071H ;    q 71
  195.            DB  072H ;    r 72
  196.            DB  073H ;    s 73
  197.            DB  074H ;    t 74
  198.            DB  075H ;    u 75
  199.            DB  076H ;    v 76
  200.            DB  077H ;    w 77
  201.            DB  078H ;    x 78
  202.            DB  060H ;    ` 79 `
  203.            DB  03AH ;    : 7A :
  204.            DB  023H ;    # 7B #
  205.            DB  040H ;    @ 7C @
  206.            DB  027H ;    ' 7D '
  207.            DB  03DH ;    = 7E =
  208.            DB  022H ;    " 7F "
  209.            DB  080H ;      80 .
  210.            DB  061H ;    a 81 a
  211.            DB  062H ;    b 82 b
  212.            DB  063H ;    c 83 c
  213.            DB  064H ;    d 84 d
  214.            DB  065H ;    e 85 e
  215.            DB  066H ;    f 86 f
  216.            DB  067H ;    g 87 g
  217.            DB  068H ;    h 88 h
  218.            DB  069H ;    i 89 i
  219.            DB  08AH ;      8A .
  220.            DB  08BH ;      8B {
  221.            DB  08CH ;      8C .
  222.            DB  08DH ;      8D .
  223.            DB  08EH ;      8E .
  224.            DB  08FH ;      8F .
  225. ;
  226. ;               PC         HOST
  227. ;              ---------- --------
  228.            DB  090H ;      90 .
  229.            DB  06AH ;    j 91 j
  230.            DB  06BH ;    k 92 k
  231.            DB  06CH ;    l 93 l
  232.            DB  06DH ;    m 94 m
  233.            DB  06EH ;    n 95 n
  234.            DB  06FH ;    o 96 o
  235.            DB  070H ;    p 97 p
  236.            DB  071H ;    q 98 q
  237.            DB  072H ;    r 99 r
  238.            DB  09AH ;      9A .
  239.            DB  09BH ;      9B }
  240.            DB  09CH ;    . 9C .
  241.            DB  09DH ;    . 9D .
  242.            DB  09EH ;    . 9E .
  243.            DB  09FH ;    . 9F .
  244.            DB  0A0H ;    . A0 .
  245.            DB  07EH ;    ~ A1 ~
  246.            DB  073H ;    s A2 s
  247.            DB  074H ;    t A3 t
  248.            DB  075H ;    u A4 u
  249.            DB  076H ;    v A5 v
  250.            DB  077H ;    w A6 w
  251.            DB  078H ;    x A7 x
  252.            DB  079H ;    y A8 y
  253.            DB  07AH ;    z A9 z
  254.            DB  0AAH ;    . AA .
  255.            DB  0ABH ;    . AB .
  256.            DB  0ACH ;    . AC .
  257.            DB  05BH ;    [ AD [
  258.            DB  0AEH ;    . AE .
  259.            DB  0AFH ;    . AF .
  260.            DB  0B0H ;    . B0 .
  261.            DB  0B1H ;    . B1 .
  262.            DB  0B2H ;    . B2 .
  263.            DB  0B3H ;    . B3 .
  264.            DB  0B4H ;    . B4 .
  265.            DB  0B5H ;    . B5 .
  266.            DB  0B6H ;    . B6 .
  267.            DB  0B7H ;    . B7 .
  268.            DB  0B8H ;    . B8 .
  269.            DB  0B9H ;    . B9 .
  270.            DB  0BAH ;    . BA .
  271.            DB  0BBH ;    . BB .
  272.            DB  0BCH ;    . BC .
  273.            DB  05DH ;    ] BD ]
  274.            DB  0BEH ;    . BE .
  275.            DB  0BFH ;    . BF .
  276. ;
  277. ;               PC         HOST
  278. ;              ---------- --------
  279.            DB  07BH ;    { C0 {
  280. ;          DB  0C0H ;    . C0 {
  281.            DB  041H ;    A C1 A
  282.            DB  042H ;    B C2 B
  283.            DB  043H ;    C C3 C
  284.            DB  044H ;    D C4 D
  285.            DB  045H ;    E C5 E
  286.            DB  046H ;    F C6 F
  287.            DB  047H ;    G C7 G
  288.            DB  048H ;    H C8 H
  289.            DB  049H ;    I C9 I
  290.            DB  0CAH ;    . CA .
  291.            DB  0CBH ;    . CB .
  292.            DB  0CCH ;    . CC .
  293.            DB  0CDH ;    . CD .
  294.            DB  0CEH ;    . CE .
  295.            DB  0CFH ;    . CF .
  296.            DB  07DH ;    } D0 }
  297.            DB  04AH ;    J D1 J
  298.            DB  04BH ;    K D2 K
  299.            DB  04CH ;    L D3 L
  300.            DB  04DH ;    M D4 M
  301.            DB  04EH ;    N D5 N
  302.            DB  04FH ;    O D6 O
  303.            DB  050H ;    P D7 P
  304.            DB  051H ;    Q D8 Q
  305.            DB  052H ;    R D9 R
  306.            DB  0DAH ;    . DA .
  307.            DB  0DBH ;    . DB .
  308.            DB  0DCH ;    . DC .
  309.            DB  0DDH ;     .DD .
  310.            DB  0DEH ;     .DE .
  311.            DB  0DFH ;     .DF .
  312.            DB  05CH ;    \ E0 \
  313.            DB  0E1H ;    . E1 .
  314.            DB  053H ;    S E2 S
  315.            DB  054H ;    T E3 T
  316.            DB  055H ;    U E4 U
  317.            DB  056H ;    V E5 V
  318.            DB  057H ;    W E6 W
  319.            DB  058H ;    X E7 X
  320.            DB  059H ;    Y E8 Y
  321.            DB  05AH ;    Z E9 Z
  322.            DB  0EAH ;    . EA .
  323.            DB  0EBH ;    . EB .
  324.            DB  0ECH ;    . EC .
  325.            DB  0EDH ;    . ED .
  326.            DB  0EEH ;    . EE .
  327.            DB  0EFH ;    . EF .
  328. ;
  329. ;               PC         HOST
  330. ;              ---------- --------
  331.            DB  030H ;    0 F0 0
  332.            DB  031H ;    1 F1 1
  333.            DB  032H ;    2 F2 2
  334.            DB  033H ;    3 F3 3
  335.            DB  034H ;    4 F4 4
  336.            DB  035H ;    5 F5 5
  337.            DB  036H ;    6 F6 6
  338.            DB  037H ;    7 F7 7
  339.            DB  038H ;    8 F8 8
  340.            DB  039H ;    9 F9 9
  341.            DB  0FAH ;    . FA .
  342.            DB  0FBH ;    . FB .
  343.            DB  0FCH ;    . FC .
  344.            DB  0FDH ;    . FD .
  345.            DB  0FEH ;    . FE .
  346.            DB  0FFH ;      FF .
  347. ;
  348. SET_ENV_lgth   DB  0
  349.                DB  "FILE="
  350. SET_ENV_NAME   DB  13 DUP (00)
  351. RN_SWITCH      DB  32            ;SET IF RN CALLS US
  352. TEMPUS_RETCODE DB  3
  353. MENU_TYPE      DB     0              ; MENU TYPE FROM PARMS
  354. M4             DB     0              ; M4 ENTERED = 4
  355. TEMPUS         DB  '\dos\command /C COPYU '
  356. TEMPUS_FILE    DB  85 DUP (00)
  357. INPUT_DIR      DB  40 DUP (00)
  358. OUTPUT_DIR     DB  40 DUP (00)
  359. VIEW_DIR       DB  69 DUP (00)
  360. LGTH_DIR       EQU 32
  361.  
  362. SAVE_KEY       DB  0
  363. FIELD_SIZE     EQU    44
  364. PAGE_START     EQU    323
  365. BAR_START      EQU    PAGE_START
  366. BAR_OFFSET     EQU    3          ;BAR OFFSET FROM BEGGINING OF LINE
  367. BAR_LENGTH     EQU    44
  368. COPY_MARK      EQU    16
  369. COPY_MARK_DONE EQU    46
  370. FCB            EQU    5CH
  371.  
  372. CURRENT_DISK   DB  ?
  373. STATUS_REG     DW  ?
  374. VIDEO_SEG      DW  0B000H
  375. NORMAL         DB  07H
  376. INVERSE        DB  70H
  377. BAR_ATTRIBUTE  DB  70H
  378. ATTR_TREE      DB     07H
  379. ATTR_MENU      DB     07H
  380. ATTR_TEXT      DB     07H
  381. ATTR_MSGS      DB     07H
  382. ATTR_SAVE      DB     07H
  383. CURSOR_TYPE    DW  ?
  384. CUR_VERIFY     DB  0
  385.  
  386. SORT_OFFSET    DW  0
  387. SORT_TABLE     DW  0,12,9,3,13,8,29
  388. SORT_FLAG      DB  0
  389. SEARCH_ATTRIB  DW  17H
  390. CUR_OFFSET     DW  BUFFER
  391. CUR_FILE       DW  ?
  392. END_OFFSET     DW  ?
  393. PAGE_END       DW  21 * 160 + BAR_START
  394. COUNT          DW  0
  395. FILE_CNT       DW  0
  396. LINE           DW  BAR_START
  397. SEARCH_COUNT   DW  ?
  398.  
  399. MARK_CNT       DW     0
  400. FILENAME_END   DW     ?
  401. PURGE_DISK     DB     ?
  402. READ_HANDLE    DW     ?
  403. WRITE_HANDLE   DW     ?
  404. SOURCE_ATTRIB  DW     ?
  405. TARGET_ATTRIB  DW     ?
  406. SIZE_LOW       DW     ?
  407. SIZE_HIGH      DW     ?
  408. SOURCE_TIME    DW     ?
  409. SOURCE_DATE    DW     ?
  410. FILE_NAME      DW     8 DUP(0)
  411. COPY_FLAG      DB     0
  412. DELETE_FLAG    DB     0
  413. RENAME_FLAG    DB     0
  414. RENAME_FILE_FLAG DB     0
  415. VERIFY_FLAG    DB     1
  416.  
  417. ERROR_EXEC     DB     0      ; ERROR FOR EXEC_MARKED
  418.  
  419. K_ESC           EQU  1
  420. K_MINUS         EQU  12
  421. K_PLUS          EQU  13
  422. K_BACKSPACE     EQU  14
  423. K_TAB           EQU  15
  424. K_Q             EQU  16
  425. K_W             EQU  17
  426. K_E             EQU  18
  427. K_R             EQU  19
  428. K_T             EQU  20
  429. K_Y             EQU  21
  430. K_U             EQU  22
  431. K_I             EQU  23
  432. K_O             EQU  24
  433. K_P             EQU  25
  434. K_L_BRACKET     EQU  26
  435. K_R_BRACKET     EQU  27
  436. K_ENTER         EQU  28
  437. K_S             EQU  31
  438. K_D             EQU  32
  439. K_C             EQU  46
  440. K_V             EQU  47
  441. K_B             EQU  48
  442. K_N             EQU  49
  443. K_M             EQU  50
  444. K_F1            EQU  59
  445. K_F2            EQU  60
  446. K_F3            EQU  61
  447. K_F4            EQU  62
  448. K_F5            EQU  63
  449. K_F6            EQU  64
  450. K_F7            EQU  65
  451. K_F8            EQU  66
  452. K_F9            EQU  67
  453. K_F10           EQU  68
  454. K_NUM_LOCK      EQU  69
  455. K_SCROLL_LOCK   EQU  70
  456. K_HOME          EQU  71
  457. K_UP_ARROW      EQU  72
  458. K_PGUP          EQU  73
  459. K_PRTSC         EQU  55
  460. KN_MINUS        EQU  74
  461. K_LEFT_ARROW    EQU  75
  462. K_RIGHT_ARROW   EQU  77
  463. KN_PLUS         EQU  78
  464. K_END           EQU  79
  465. K_DOWN_ARROW    EQU  80
  466. K_PGDN          EQU  81
  467. K_INS           EQU  82
  468. K_DEL           EQU  83
  469. K_LEFT_SHIFT    EQU  42
  470. K_RIGHT_SHIFT   EQU  36
  471. K_TAB           EQU  15
  472. K_CTRL          EQU  29
  473. K_ALT           EQU  56
  474. K_SPACE         EQU  57
  475. K_CAPS_LOCK     EQU  58
  476. K_CTRL_PGDN     EQU  118
  477. K_CTRL_PGUP     EQU  132
  478.  
  479. DEFAULT_MENU   DB  2       ;DEFAULT IS MENU  2
  480.  
  481. DISPATCH_KEY   DB  K_ESC,  K_F7,         K_F6,       K_F8
  482.                DB  K_ENTER
  483.                DB  K_F10,  K_F9
  484.                DB  KN_MINUS, KN_PLUS
  485.                DB  K_MINUS,  K_PLUS
  486.                DB  K_DEL,    K_INS
  487.                DB  K_F4
  488.                DB  K_B
  489.                DB  K_F5
  490.                DB  K_R
  491. DISPATCH_KF2   DB  K_F2
  492.                DB  K_F3
  493.                DB  K_S
  494.                DB  K_E
  495.                DB  K_W
  496. ;              DB  K_T,        K_S,    K_N
  497.                DB  K_D,    K_C,          K_V,
  498.                DB  K_M,
  499.                DB  K_HOME,       K_UP_ARROW, K_PGUP
  500.                DB  K_END,  K_DOWN_ARROW, K_PGDN,  K_CTRL_PGDN
  501.                DB  K_CTRL_PGUP
  502.                DB  K_LEFT_ARROW
  503.                DB  K_RIGHT_ARROW
  504. DISPATCH_CNT   EQU $ - DISPATCH_KEY
  505.  
  506. DISPATCH_TABLE DW  ESC_EXIT,   COPY,      DELETE,    MOVE,
  507.                DW  SELECT
  508.                DW  CLEAR_MARK, MARK_BLANK
  509.                DW  UNMARK,     MARK
  510.                DW  UNMARK,     MARK
  511.                DW  UNMARK,     MARK
  512.                DW  VIEW
  513.                DW  VIEW
  514.                DW  RENAME
  515.                DW  RENAME
  516. DISPATCH_F2    DW  NO_OP
  517.                DW  SORT_TYPE
  518.                DW  SORT_TYPE
  519.                DW  EBCDIC
  520.                DW  WORDSTAR
  521. ;              DW  SORT_DATE, SORT_SIZE,  SORT_NAME
  522.                DW  DELETE,     COPY,      VERIFY,
  523.                DW  MOVE,
  524.                DW  HOME_BAR,  UP_ARROW,  PG_UP
  525.                DW  END_BAR,    DN_ARROW,  PG_DN,     BOTTOM_BAR,
  526.                DW  TOP_BAR
  527.                DW  MARK_UNMARK
  528.                DW  TO_MENU
  529. DISPATCH_END   EQU $ - 2
  530.  
  531. ;------------------FW MENU2---------------------------------------
  532. DISPATCH_KEY2  DB  K_ESC
  533.                DB  K_ENTER
  534.                DB  K_F4
  535. DISPATCH_KF2_2 DB  K_F2
  536.                DB  K_HOME,       K_UP_ARROW, K_PGUP
  537.                DB  K_END,  K_DOWN_ARROW, K_PGDN,  K_CTRL_PGDN
  538.                DB  K_CTRL_PGUP
  539.                DB  K_RIGHT_ARROW
  540. DISPATCH_CNT2  EQU $ - DISPATCH_KEY2
  541.  
  542. DISPATCH_TABLE2 DW  ESC_EXIT
  543.                DW  SELECT
  544.                DW  NEW_MENU
  545. DISPATCH_F2_2  DW  NO_OP
  546.                DW  HOME_BAR,  UP_ARROW,  PG_UP
  547.                DW  END_BAR,    DN_ARROW,  PG_DN,     BOTTOM_BAR,
  548.                DW  TOP_BAR
  549.                DW  TO_MENU
  550. DISPATCH_END2  EQU $ - 2
  551. ;-----------------------------------------------------------------
  552.  
  553. ;-----------------VIEW DATA-----------------------------------------
  554. BP_STACK       EQU    20480
  555. FILE_BUFFER    EQU    32767-500
  556. SIXTEEN_K      EQU    16384
  557. PAGES          DW  ?
  558. DISPLAY_FLAG   DB  ?
  559. ROW            DB  0
  560. FILE_END       DW  ?
  561. FILE_HANDLE    DW  ?
  562. LAST_PAGE      DW  ?
  563. WORDSTAR_BIT   DB  7FH
  564. EBCDIC_FLAG    DB  0
  565.  
  566. VIEW_KEY       DB  K_ESC,  K_ENTER,
  567.                DB  K_HOME,       K_UP_ARROW, K_PGUP,      K_END
  568.                DB  K_DOWN_ARROW, K_PGDN,     K_CTRL_PGDN, K_CTRL_PGUP
  569. VIEW_CNT       EQU $ - VIEW_KEY
  570.  
  571. VIEW_TABLE     DW  VIEW_END,  VIEW_END
  572.                DW  HOME_FILE, UP_LINE, UP_PG,    END_FILE
  573.                DW  DN_LINE,   DN_PG,   END_FILE, HOME_FILE
  574. VIEW_TABLE_END EQU $ - 2
  575. ;-------------------------------------------------------------------
  576.  
  577. MENU_WIDTH   EQU  31
  578. MENU_LGTH    EQU  20
  579.  
  580. MENU  LABEL  BYTE
  581.             DB  201,29 DUP (205),          187
  582.             DB  186,"      PC Magazine CO.COM     ",186
  583.             DB  199,29 DUP (196)          ,182
  584.             DB  186," Enter ",17,196,217," Select & End Pgm  ",186
  585. MENU_F2     DB  186,"                             ",186
  586.             DB  186," F3  ^Sort directory names   ",186
  587.             DB  186," F4  ^Browse selected file   ",186
  588.             DB  186," F5  ^Rename File(s)         ",186
  589.             DB  186," F6  ^Delete File(s)         ",186
  590.             DB  186," F7  ^Copy File(s)           ",186
  591.             DB  186," F8  ^Move File(s)           ",186
  592.             DB  186," F9   Mark all files         ",186
  593.             DB  186," F10  Clear all marked Files ",186
  594.             DB  186,"       Toggles (on/off)      ",186
  595. OPTION_LN   DB  186," √^Verify  ^EBCDIC  ^Wordstar",186
  596. VERIFY_ON   EQU  OPTION_LN+2
  597. EBCDIC_ON   EQU  OPTION_LN+11
  598. WORDSTAR_ON EQU  OPTION_LN+20
  599.             DB  186," +/- Ins/Del to Mark/Unmark  ",186
  600.             DB  186," Esc to Cancel Program       ",186
  601.             DB  200,29 DUP (205),          188
  602.             DB  "      Use: ",24,32,25," PgUp PgDn     "
  603.             DB  "       ^PgUp ^PgDn Home End      "
  604.  
  605. ;-----------------FW MENU2-------------------------------
  606. MENU2 LABEL  BYTE
  607.             DB  201,29 DUP (205),187,
  608.             DB  186,"      PC Magazine CO.COM     ",186
  609.             DB  199,29 DUP (196),182
  610.             DB  186,'To SELECT, use the ',24,' ',25,' cursor',186
  611.             DB  186,' keys or the mouse to move   ',186
  612.             DB  186,' the HIGHLIGHTED box to the  ',186
  613.             DB  186,' File you wish, then press   ',186
  614.             DB  186,' the left mouse botton or the',186
  615.             DB  186,'Enter ',17,196,217,' key.               ',186
  616.             DB  186,'                             ',186
  617. MENU_F2_2   DB  186,"                             ",186
  618.             DB  186,'                             ',186
  619.             DB  186,'                             ',186
  620.             DB  186,' F4   Maintenance functions  ',186
  621.             DB  186,'      for files.             ',186
  622.             DB  186,'                             ',186
  623.             DB  186,' Esc to Cancel Program       ',186
  624.             DB  200,29 DUP (205),188,
  625.             DB '      Use: ',24,32,25,' PgUp PgDn       '
  626.             DB    '     ^PgUp ^PgDn Home End      '
  627.  
  628. MENU_M3     DB  186," F2   New Project Copy File  ",186,0
  629.  
  630. NOT_ENOUGH     DB  "Requires 128K free RAM$"
  631. INVALID        DB  "Invalid directory$"
  632. TOO_MANY       DB  "Too many files$"
  633. LOADING        DB  "Loading and Sorting directory.",0
  634. LOAD_ONLY      DB  "Loading directory.",0
  635. NO_FILES       DB  "NO FILES FND",0
  636. DIRECTORY      DB  "Directory of ",0
  637. COPY_MOVE   DB  " [NOTE: Copy & Move functions SEND Data to -",16,32,0
  638. FILES          DB  4 DUP(32),"File(s)",11 DUP(32),"bytes free",0
  639. DELETE_MSG     DB  " will be Deleted.",0,"Do you wish to delete?  Y/N",0
  640. BS             DB  8,32,8,0
  641. DISK_MSG       DB  "Error reading drive ",0
  642.                DB  "(R)etry or (Q)uit",0
  643. MARKED_MSG     DB  " marked files",0
  644. COPY_MSG       DB  "Copy ",0
  645. COPY_MODEL_MSG  DB  "Enter New Project name ",0
  646. COPY_MODEL_MSG2 DB  "for copy of ",0
  647. MODEL          DB  "MODEL"
  648. BAK            DB  ".BAK"
  649. COPY_MODEL_ERR DB  "Only one file can be selected!",0
  650. MOVE_MSG       DB  "Move ",0
  651. RENAME_MSG     DB  "Rename ",0
  652. TO_MSG         DB  " to...",0
  653. STAR_DOT_STAR  DB  "*.*",11 DUP (0)
  654. SAVE_LAST_SLASH DW  ?
  655. IS_THERE_FILE  DB  0
  656. ON             DB  " ON",0
  657. OFF            DB  "OFF",0
  658. DIRECTORIES    DB  "<DIR>"
  659. SORT_MSG1      DB  "Enter type of sort for files",0
  660. SORT_MSG2      DB  "Name Extention Size Date or Time",0
  661.  
  662.  
  663. ;----------------------------------------------------------------------------;
  664. ; Some housekeeping first. Since we will be changing the default drive
  665. ;
  666. ; and directory to the requested drive and directory, we need to save the
  667. ;
  668. ; current defaults, so they can be restored.  Install critical error trap
  669. ;----------------------------------------------------------------------------;
  670.  
  671. ;              CODE AREA
  672. ;              ---------
  673. BEGINNING:     MOV    AX,3301H               ;Turn Control Break off.
  674.                MOV    DL,0
  675.                INT    21H
  676.  
  677.                MOV    AH,54H                 ;Get current verify flag.
  678.                INT    21H
  679.                MOV    CUR_VERIFY,AL          ; and save.
  680.                MOV    AL,01
  681.                CALL   SET_VERIFY             ;Turn verify oN
  682.                MOV    DX,OFFSET DISK_ERROR   ;Install critical error trap
  683.                MOV    AX,2524H
  684.                INT    21H
  685.  
  686.                CLD                           ;String moves forward.
  687.                CALL   GET_DRIVE              ;Get current drive.
  688.                MOV    CURRENT_DISK,AL        ;Save.
  689.                MOV    SI,OFFSET CURRENT_DIR  ;Get current directory.
  690.                CALL   GET_DIR
  691.  
  692. ;---------------------------------------------------------------------;
  693. ; More housekeeping. We will be writing directly to the screen buffer ;
  694. ; so we need the display card address and the status register.        ;
  695. ;---------------------------------------------------------------------;
  696.  
  697. DISPLAY:       MOV    AX,40H           ;Point to the ROM BIOS data area
  698.                MOV    DS,AX            ; and get base address of active
  699.                MOV    AX,DS:[63H]      ; display card.
  700.                ADD    AX,6             ;Add six to get status register
  701.                PUSH   CS               ;Done there, so restore data segment.
  702.                POP    DS
  703.                MOV    STATUS_REG,AX    ;Store status register.
  704.                CMP    AX,3BAH          ;Status port of MONO card is 3BAh.
  705.                JZ     MONO             ;If that's what we got, it's MONO
  706.                MOV    VIDEO_SEG,0B800H       ; else COLOR so add 800h.
  707.                XOR    BH,BH                  ;Get current attribute
  708.                MOV    AH,8                   ; of display page zero.
  709.                INT    10H
  710.                MOV    NORMAL,AH              ;Store it.
  711.                MOV    AH,07
  712.                XOR    AH,1110111xB            ;Flip color bits.
  713.                MOV    INVERSE,AH             ;Save it.
  714.                MOV    BAR_ATTRIBUTE,AH
  715.                MOV    ATTR_TREE,14           ;Store it.
  716.                MOV    ATTR_MENU,03           ;Store it.
  717.                MOV    ATTR_TEXT,02           ;Store it.
  718.                MOV    ATTR_MSGS,04           ;Store it.
  719. MONO:          XOR    BH,BH
  720.                MOV    AH,3                   ;Retrieve cursor type.
  721.                INT    10H
  722.                MOV    CURSOR_TYPE,CX
  723.  
  724.                MOV    AH,49H                 ;Return our memory segment.
  725.                INT    21H
  726.  
  727.                MOV    BX,2000H               ;Request 128K.
  728.                MOV    AH,4AH
  729.                INT    21H
  730.                MOV    DX,OFFSET NOT_ENOUGH
  731.                JNC    PARSE
  732.                JMP    ERROR_EXIT         ;If not available, exit.
  733.  
  734. ;----------------------------------------;
  735. ; Parse the command line for parameters. ;
  736. ;----------------------------------------;
  737.  
  738. PARSE:         MOV    SI,81H                 ;Point to first character.
  739.                CMP    BYTE PTR DS:[80H],0    ; Any parameters?
  740.                JNZ    NEXT_SWITCH
  741.                JMP    GET_WORKING            ;If no, skip.
  742.  
  743. NEXT_SWITCH:   LODSB                         ;Get a byte.
  744.                CMP    AL,13                  ;Carriage return?
  745.                JNE    NEXT_SWITCH_1
  746.                JMP    GET_PARA               ;If yes, done here.
  747. NEXT_SWITCH_1: CMP    AL,"-"                 ;Is it RN switch character?
  748.                JNZ    NEXT_REG_SW            ;If no, CHECK next character
  749.                MOV    RN_SWITCH,"-"          ;SET IT
  750.  
  751.                JMP    NEXT_LOAD
  752. NEXT_REG_SW:   CMP    AL,"/"                 ;Is it switch character?
  753.                JNZ    NEXT_SWITCH            ;If no, get next character.
  754. NEXT_LOAD:     LODSB                         ;Get switch character.
  755.                AND    AL,5FH                 ;Capitalize.
  756.                CMP    AL,"R"                 ;If "R", remove directories.
  757.                JNZ    CK_EXT
  758.                MOV    SEARCH_ATTRIB,7
  759. CK_EXT:        CMP    AL,"E"                 ;If "E", sort by extension.
  760.                JNZ    CK_SIZE
  761.                MOV    SORT_OFFSET,4
  762. CK_SIZE:       CMP    AL,"S"                 ;If "S", sort by size.
  763.                JNZ    CK_DATE
  764.                MOV    SORT_OFFSET,8
  765. CK_DATE:       CMP    AL,"D"                 ;If "D", sort by date.
  766.                JZ     GOT_DATE
  767.                CMP    AL,"T"                 ;If "T", sort by date.
  768.                JNZ    CK_ORIGINAL
  769. GOT_DATE:      MOV    SORT_OFFSET,12
  770.  
  771. CK_ORIGINAL:   CMP    AL,"O"                 ;If "O", don't sort at all.
  772.                JNZ    CK_MENU
  773.                MOV    SORT_FLAG,1
  774. CK_MENU:       CMP    AL,"M"                 ;If "M", M1,M2,M3.....
  775.                JNE    NEXT_SWITCH
  776.                LODSB                         ;Get switch character.
  777.                MOV    MENU_TYPE,AL           ;SAVE TYPE
  778.                CMP    AL,"3"                 ;/m3
  779.                JNE    CK_MENU_4
  780.                MOV    SI,OFFSET MENU_M3      ;NEW MENU LINE
  781.                MOV    DI,OFFSET MENU_F2      ;WHERE TO MOVE
  782.                CALL   MOVE_TEXT              ;MOVE IT
  783.                MOV    SI,OFFSET MENU_M3      ;NEW MENU LINE
  784.                MOV    DI,OFFSET MENU_F2_2    ;WHERE TO MOVE
  785.                CALL   MOVE_TEXT              ;MOVE IT
  786.                MOV    BX,OFFSET COPY_MODEL
  787.                MOV    WORD PTR DISPATCH_F2,BX ;NEW
  788.                MOV    WORD PTR DISPATCH_F2_2,BX ;NEW
  789.  
  790. CK_MENU_4:     CMP    AL,"4"                 ;/m4
  791.                JNE    CK_NEXT_MENU
  792.                MOV    DEFAULT_MENU,1         ;DEFAULT TO LONG MENU
  793.                MOV    M4,4                   ;SAY M4 ENTERED
  794.  
  795. CK_NEXT_MENU:
  796.                JMP    SHORT NEXT_SWITCH
  797.  
  798. GET_PARA:      XOR    BL,BL                  ;Assume no drive request.
  799.                MOV    SI,81H                 ;Point to first character.
  800.  
  801. NEXT_PARA:     MOV    DI,OFFSET INPUT_DIR
  802.                CMP    INPUT_DIR,00           ;IF INPUT BLANK
  803.                JZ     NEXT_SCAN              ;GOOD
  804.                MOV    DI,OFFSET OUTPUT_DIR   ;ELSE POINT TO OUTPUT DIR
  805. NEXT_SCAN:     LODSB
  806. NEXT_SCAN_1:   CMP    AL,32                  ;End of parameter?
  807.                JE     NEXT_SCAN              ;If yes, NEXT BYTE.
  808.                CMP    AL,13                  ;End of parameter?
  809.                JE     END_PARA               ;If yes, done here.
  810.  
  811.                CMP    AL,"-"
  812.                JE     NEXT_BLANK_P
  813.                CMP    AL,"/"
  814.                JE     NEXT_BLANK_P
  815.                MOV    CX,LGTH_DIR
  816.                DEC    CX
  817.                STOSB
  818. NEXT_LOOP:     LODSB
  819.                CMP    AL,13                  ;End of parameter?
  820.                JE     END_PARA               ;If yes, done here.
  821.                CMP    AL,32                  ;End of parameter?
  822.                JE     NEXT_PARA              ;If yes, NEXT PARAMETER
  823.  
  824.                CMP    AL,64
  825.                JBE    NO_CAPS
  826.                AND    AL,5FH                 ;Capitalize.
  827. NO_CAPS:       STOSB
  828.                DEC    CX
  829.                JZ     NEXT_PARA
  830.                JMP    NEXT_LOOP              ; GET NEXT CHAR
  831.  
  832. NEXT_BLANK_P:  LODSB
  833.                CMP    AL,13                  ;End of parameter?
  834.                JE     END_PARA               ;If yes, done here.
  835.                CMP    AL,32                  ;End of parameter?
  836.                JNE    NEXT_BLANK_P           ;If NO, NEXT BYTE.
  837.                JMP    NEXT_SCAN_1            ; GET PARAMETER
  838.  
  839. END_PARA:      CMP    RN_SWITCH,32           ;DID RN CALL
  840.                JNE    NO_DRIVE_CHG
  841.                CMP    INPUT_DIR+1,":"        ;DRIVE REQUEST
  842.                JNE    NO_DRIVE_CHG
  843.                MOV    DL,INPUT_DIR
  844.                SUB    DL,"A"                 ;Convert to DOS format.
  845.                CALL   CHANGE_DRIVE           ;And change drive.
  846. NO_DRIVE_CHG:  MOV    SI,OFFSET INPUT_DIR
  847.                MOV    SAVE_LAST_SLASH,SI     ;SAVE POINTER
  848. PARA_LOOP:     MOV    AL,BYTE PTR [SI]       ;LOAD CHAR
  849.                CMP    AL,00                  ;FIND END OF PARAMETER
  850.                JE     PARA_LOOP_END
  851. CHECK_COLEN:   CMP    AL,':'                 ;IS THERE A :
  852.                JNE    CHECK_SLASH
  853.                MOV    SAVE_LAST_SLASH,SI     ;SAVE POINTER
  854. CHECK_SLASH:   CMP    AL,'\'                 ;IS THERE A \
  855.                JNE    CHECK_ASTRISK
  856.                MOV    SAVE_LAST_SLASH,SI     ;SAVE POINTER
  857. CHECK_ASTRISK: CMP    AL,'*'                 ;IS THERE A *
  858.                JNE    CHECK_QUESTION
  859.                MOV    IS_THERE_FILE,1        ;SAY YES
  860. CHECK_QUESTION: CMP   AL,'?'                 ;IS THERE A ?
  861.                JNE    CHECK_DONE
  862.                MOV    IS_THERE_FILE,1        ;SAY YES
  863. CHECK_DONE:    INC    SI
  864.                CMP    SI,OFFSET INPUT_DIR+LGTH_DIR
  865.                JAE    PARA_LOOP_END
  866.                JMP    SHORT PARA_LOOP
  867. PARA_LOOP_END:
  868.                MOV    BYTE PTR [SI],0   ;Convert parameter to ASCIIZ.
  869.                CMP    IS_THERE_FILE,0      ;IS THERE A FILE PARAMETER
  870.                JE     GET_WORKING
  871.                MOV    SI,SAVE_LAST_SLASH
  872.                MOV    BYTE PTR [SI],0   ;Convert parameter to ASCIIZ.
  873.                INC    SI
  874.                MOV    DI,OFFSET STAR_DOT_STAR
  875.                MOV    CX,12                ;MAX FILE LGTH
  876.                REP    MOVSB
  877.                MOV    BYTE PTR [DI],0   ;Convert parameter to ASCIIZ.
  878.  
  879. GET_WORKING:   CALL   READ_DIR             ;PUT DIR STUFF IN MEMORY
  880.                MOV    SI,OFFSET VIEW_DIR   ;Get current directory.
  881.                CALL   GET_DIR
  882.                CMP    PURGE_DIR+3 W,"WD"   ;DW?? DIR DISPLAYWRITE
  883.                JNZ    GET_KEY              ;NO
  884.                CALL   EBCDIC               ;TURN EBCDIC ON
  885.  
  886. ;-----------------------------------------;
  887. ; We are ready for business now. We will  ;
  888. ; loop here, waiting for user key strokes.;
  889. ;-----------------------------------------;
  890.  
  891. GET_KEY:       CALL   UPDATE_SCREEN
  892.                CALL   READ_KEY               ;Get a keystroke.
  893.                MOV    BX,AX                  ;Save returned key.
  894.                CMP    AH,1                   ;Is it Esc or below?
  895.                JBE    FUNCTION               ;If yes, function.
  896.                CMP    AH,36H                 ;Is it right shift or above?
  897.                JAE    FUNCTION               ;If yes, function.
  898.  
  899.                CMP    AH,1CH                 ;Is it CR?
  900.                JZ     FUNCTION               ;If yes, function.
  901.                MOV    AH,2                   ;Get shift state.
  902.                INT    16H
  903.                TEST   AL,4                   ;Is Ctrl depressed?
  904.                JNZ    FUNCTION               ;If no, check function request.
  905.                CALL   SEARCH                 ;Else, search for first letter.
  906.                JMP    SHORT GET_KEY
  907.  
  908. FUNCTION:
  909.                CMP    DEFAULT_MENU,2
  910.                JE     FUNCTION2
  911.                MOV    DI,OFFSET DISPATCH_KEY
  912.  
  913.                MOV    AL,BH
  914.                MOV    CX,DISPATCH_CNT        ;Valid commands.
  915.                REPNZ  SCASB
  916.                JNZ    GET_KEY                ;If no match, get another.
  917.                MOV    DI,OFFSET DISPATCH_END
  918.                JMP    FUNCTION_EXE
  919.  
  920. FUNCTION2:
  921.                MOV    DI,OFFSET DISPATCH_KEY2
  922.  
  923.                MOV    AL,BH
  924.                MOV    CX,DISPATCH_CNT2       ;Valid commands.
  925.                REPNZ  SCASB
  926.                JNZ    GET_KEY                ;If no match, get another.
  927.                MOV    DI,OFFSET DISPATCH_END2
  928.  
  929. FUNCTION_EXE:  SHL    CX,1
  930.  
  931.                SUB    DI,CX
  932.                CALL   DS:[DI]                ;Else do subroutine.
  933.                JMP    SHORT GET_KEY          ;Update screen; get next command.
  934.  
  935.                ;*************;
  936.                ; SUBROUTINES ;
  937.                ;*************;
  938.  
  939. TO_MENU:       RET
  940. NO_OP:         RET
  941.  
  942. ;------------------------------------------------------------------------;
  943. ; This subroutine CHANGES THE DEFAULT MENU FROM SHORT TO LONG            ;
  944. ;------------------------------------------------------------------------;
  945.  
  946. NEW_MENU:
  947.                MOV  DEFAULT_MENU,1         ;DEFAULT TO LONG MENU
  948.                CALL REFRESH_MENU           ;AND DISPLAY IT
  949.                RET
  950. ;------------------------------------------------------------;
  951. ; This subroutine does special processing related to the /M3 ;
  952. ; switch. It will oes special processing related to the /M3 ;
  953. ;------------------------------------------------------------;
  954. COPY_MODEL:
  955.                CALL   CLEAR_MSG
  956.                CALL   COUNT_MARKS            ;Count marks.
  957.                CMP    CX,1                   ;ONE marked file?
  958.                JE     COPY_MODEL_DEST        ;If yes, display "Copy" message.
  959.                JB     COPY_MODEL_DIR
  960.                CALL   CLEAR_MSG
  961.                MOV    DX,172FH
  962.                MOV    SI,OFFSET COPY_MODEL_ERR
  963.                CALL   DISPLAY_TEXT
  964.                JMP    COPY_MODEL_ERROR       ;If yes, exit.
  965. COPY_MODEL_DIR:
  966.                CALL   GET_NAME               ;Is the highlighted a directory?
  967.                JNC    COPY_MODEL_DEST        ;If yes, exit.
  968.                JMP    COPY_MODEL_ERROR       ;If yes, exit.
  969. COPY_MODEL_DEST:
  970.                MOV    DX,162FH
  971.                MOV    SI,OFFSET COPY_MODEL_MSG
  972.                CALL   DISPLAY_TEXT
  973.                MOV    DX,172FH
  974.                MOV    SI,OFFSET COPY_MODEL_MSG2
  975.                CALL   DISPLAY_TEXT
  976.                MOV    AX,"  "
  977.                MOV    WORD TO_MSG+1,AX       ;REMOVE Display " to..."
  978.                CALL   DESTINATION            ;Ask user for destination.
  979.                JC     EXIT_MODEL_COPY        ;If Esc pressed, exit.
  980.                MOV    DI,OFFSET ENTRY  B     ;SET INPUT FOR ENVIRONMENT
  981.                MOV    AL,'.'                 ;FIND
  982.                MOV    CX,10                  ; '.. IF THERE
  983.                REPNZ  SCASB
  984.                JNE    COPY_MODEL_NO_EXT
  985.                DEC    DI
  986.                MOV    SI,OFFSET BAK
  987.                MOV    CX,4                   ;Compare "BAK"
  988.                REPE   CMPSB
  989.                JNE    COPY_MODEL_EXT
  990.                JMP    COPY_MODEL            ;GET ANOTHER NAME .BAK NG
  991. COPY_MODEL_NO_EXT:
  992.                MOV    DI,FILE_NAME           ;SET FILE NAME FOR COMPARE
  993.                MOV    AL,"."                 ;FIND
  994.                MOV    CX,12                  ;BINARY 00
  995.                REPNZ  SCASB
  996.                DEC    DI
  997.                MOV    SI,OFFSET BAK
  998.                MOV    CX,4                   ;Compare "BAK"
  999.                REPE   CMPSB
  1000.                JNE    COPY_MODEL_AST
  1001.                JMP    COPY_MODEL             ;DO AGAIN UNTIL NOT BAK
  1002. COPY_MODEL_AST: MOV    DI,OFFSET ENTRY  B     ;SET INPUT FOR ENVIRONMENT
  1003.                MOV    AL,00                  ;FIND
  1004.                MOV    CX,10                  ;BINARY 00
  1005.                REPNZ  SCASB
  1006.                DEC    DI
  1007.                MOV    BYTE PTR [DI],"."
  1008.                INC    DI
  1009.                MOV    BYTE PTR [DI],"*"
  1010. COPY_MODEL_EXT:
  1011.                MOV    AX,"to"
  1012.                MOV    WORD TO_MSG+1,AX       ;restore Display " to..."
  1013.                MOV    COPY_FLAG,1            ;Else, indicate copy.
  1014.                MOV    ERROR_EXEC,0           ;SAY NO ERRORS
  1015.                CALL   EXEC_MARKED            ;Execute the command.
  1016.                CMP    ERROR_EXEC,0           ;SAY NO ERRORS
  1017.                JNE    EXIT_MODEL_COPY
  1018.                MOV    COPY_FLAG,0            ;Restore copy flag.
  1019.                MOV    SI,OFFSET TARGET B     ;SET INPUT FOR ENVIRONMENT
  1020.                JMP    SELECT_MOVE            ;GO TO MOVE AND END
  1021. EXIT_MODEL_COPY:
  1022.                CALL   READ_DIR               ;PUT DIR STUFF IN MEMORY
  1023.                RET
  1024.  
  1025. COPY_MODEL_ERROR:
  1026.                CALL   BEEP
  1027.                RET
  1028.  
  1029. ;----------------------------------------------------------------------;
  1030. ; This subroutine selects the highlighted file for processing. The type;
  1031. ;of processing is determined by the function being performed. If an    ;
  1032. ;output drive or directory is entered the files selected are copied to ;
  1033. ;that drive or directory. Switch /M3 changes the function of the F2 key;
  1034. ;from sort directory to copy file to new name and put the name into the;
  1035. ;environment. This routine will also look for special file name        ;
  1036. ;"MODEL.???" and copy that file to a new name then put that name in the;
  1037. ;environment.  The purpose of these last 2 functions is to provide a   ;
  1038. ;facility which will allow SuperProject to startup using a an existing ;
  1039. ;project or a model project.                                           ;
  1040. ;----------------------------------------------------------------------;
  1041.  
  1042. SELECT:
  1043.                CMP    OUTPUT_DIR,00          ;WAS THERE AN OUTPUT ENTERE
  1044.                JE     SELECT_ONLY            ;IF NOT JUST SELECT
  1045.                JMP    COPY                   ;ELSE DO COPY FUNCITON
  1046. SELECT_ONLY:   CALL   GET_NAME               ;Get the file name.
  1047.                JC     SELECT_ERROR           ;If directory, skip.
  1048.                CMP    MENU_TYPE,"3"          ;/m3
  1049.                JNE    SELECT_F_NAME
  1050.                MOV    SI,OFFSET MODEL
  1051.                MOV    DI,FILE_NAME
  1052.                MOV    CX,5                   ;Compare "MODEL"
  1053.                REPE   CMPSB
  1054.                JNE    SELECT_BAK
  1055.                JMP    COPY_MODEL             ;If above, swap.
  1056. SELECT_BAK:    MOV    DI,FILE_NAME           ;SET FILE NAME FOR COMPARE
  1057.                MOV    AL,"."                 ;FIND
  1058.                MOV    CX,12                  ;BINARY 00
  1059.                REPNZ  SCASB
  1060.                JNZ    SELECT_F_NAME
  1061.                DEC    DI
  1062.                MOV    SI,OFFSET BAK
  1063.                MOV    CX,4                   ;Compare "BAK"
  1064.                REPE   CMPSB
  1065.                JNE    SELECT_F_NAME
  1066.                JMP    COPY_MODEL             ;If above, swap.
  1067. SELECT_F_NAME: MOV    SI,FILE_NAME
  1068. SELECT_MOVE:   MOV    DI,OFFSET SET_ENV_NAME
  1069.                MOV    CX,13                  ;13 characters MAX
  1070. SELECT_LOOP:   LODSB
  1071.                STOSB
  1072.                CMP    AL,00
  1073.                JZ     SELECT_SET_ENV
  1074.                LOOP   SELECT_LOOP
  1075. SELECT_SET_ENV:
  1076.                MOV    CX,OFFSET SET_ENV_LGTH    ;FIND ENV SET LGTH
  1077.                MOV    AX,DI
  1078.                SUB    AX,CX                     ;
  1079.                DEC    AX                        ;-1
  1080.                DEC    AX                        ;-1
  1081.                MOV    SET_ENV_LGTH,AL           ; SET LGTH OF ENV STING
  1082.                MOV    SI,offset SET_ENV_LGTH    ;address of set string
  1083.                CALL   ENV_SET                   ;change environment per ds:si
  1084.                MOV    AX,4D00H                  ;Get Return Code
  1085.                INT    21H
  1086.                MOV    DI,OFFSET TEMPUS_RETCODE ;Load Return Code Addr
  1087.  
  1088.                STOSB
  1089.                JMP    TERMINATE
  1090. SELECT_ERROR:
  1091.                CALL   BEEP
  1092.                RET
  1093.  
  1094.  
  1095. ;------------------------------------------------------------;
  1096. ; This subroutine displays the highlighted file for viewing. ;
  1097. ;------------------------------------------------------------;
  1098. ;=======================================================================
  1099. VIEW:
  1100.                PUSH   BP                     ;Get the file name.
  1101.                MOV    PAGES,BP_STACK
  1102.                CALL   GET_NAME               ;Get the file name.
  1103.                MOV    DX,OFFSET SOURCE B     ;Open the file.
  1104.                MOV    AX,3D00H
  1105.                INT    21H
  1106.                MOV    FILE_HANDLE,AX         ;Save filehandle.
  1107.  
  1108.                CALL   FIRST_READ
  1109.                MOV    LAST_PAGE,OFFSET FILE_BUFFER+SIXTEEN_K
  1110.                MOV    BP,PAGES               ;Initialize page pointer.
  1111.                MOV    ROW,0                  ;And row pointer.
  1112.                CALL   CLS_TEXT               ;Clear screen.
  1113.  
  1114. GET_VIEW:      MOV    SI,LAST_PAGE           ;Get top of current page.
  1115.                MOV    BH,ROW                 ;Get row offset into page.
  1116.                CMP    BH,0                   ;Is it row zero?
  1117.                JZ     NEXT_VIEW              ;If yes, skip.
  1118.                MOV    DISPLAY_FLAG,0         ;No display.
  1119. PAGE_OFFSET:   CALL   LINES
  1120.                DEC    BH
  1121.                JNZ    PAGE_OFFSET
  1122.  
  1123. NEXT_VIEW:     MOV    BH,25                  ;Now display 25 lines.
  1124.                XOR    DI,DI                  ;Start at top left corner.
  1125.  
  1126.                MOV    DISPLAY_FLAG,1         ;Display.
  1127. VIEW_DISPLAY:  CALL   LINES
  1128.                DEC    BH
  1129.                JNZ    VIEW_DISPLAY
  1130.  
  1131. VIEW_COMMAND:  CALL   READ_KEY               ;Get a keystroke.
  1132.                MOV    AL,AH                  ;Save returned key.
  1133.                CMP    AL,K_ESC               ;Is it Esc?
  1134.                JZ     VIEW_END               ;If yes, exit view.
  1135.                CMP    AL,K_ENTER             ;Is it carriage return?
  1136.                JZ     VIEW_END               ;If yes, exit view.
  1137.                CMP    AL,K_F3                ;Is it F3?
  1138.                JZ     VIEW_END               ;If yes, exit.
  1139. ;------------------FW CHANGE------------------------------------------
  1140. GET_DISPATCH:  MOV    DI,OFFSET VIEW_KEY
  1141.                MOV    AL,AH
  1142.                MOV    CX,VIEW_CNT            ;Valid commands.
  1143.                REPNZ  SCASB
  1144.                JNZ    VIEW_COMMAND           ;If no match, get another.
  1145.                MOV    DI,OFFSET VIEW_TABLE_END
  1146.  
  1147.                SHL    CX,1
  1148.                SUB    DI,CX
  1149.                CALL   DS:[DI]                ;Else do subroutine.
  1150.                JC     VIEW_COMMAND           ;Carry indicates no screen update.
  1151.                JMP    GET_VIEW               ;Update screen; get next command.
  1152. ;---------------------------------------------------------------------
  1153. VIEW_END:      MOV    BX,FILE_HANDLE         ;Close the file.
  1154.                MOV    AH,3EH
  1155.                INT    21H
  1156.                CALL   CLS
  1157.                CALL   REFRESH_DIR            ;Restore menu.
  1158.                POP    BP
  1159.                RET
  1160.  
  1161. VIEW_REQUEST:  CALL   VIEW_END               ;If request of another function,
  1162.                CALL   UPDATE_SCREEN          ; close file and update screen.
  1163.                POP    BP
  1164.                RET
  1165.  
  1166. ;----------------------------------------------------------------------;
  1167. ; These six subroutines control the page and starting row of the view. ;
  1168. ;----------------------------------------------------------------------;
  1169. UP_LINE:       CMP    ROW,0                  ;Are we at row zero?
  1170.                JNZ    DEC_ROW                ;If no, decrement one row.
  1171.                CMP    BP,PAGES               ;Else, are we at first page?
  1172.                STC
  1173.                JZ     UP_LINE_END            ;If yes, no change.
  1174.                CALL   UP_PG                  ;Else, move up one page.
  1175.                MOV    ROW,25                 ;And move starting row to 25
  1176. DEC_ROW:       DEC    ROW                    ;Decrement row.
  1177.                CLC                           ;Flag to update screen.
  1178. UP_LINE_END:   RET
  1179.  
  1180. DN_LINE:       CALL   CK_FILE_END            ;Are we at end of file?
  1181.                JNC    CK_ROW                 ;If no, check row.
  1182.                RET                           ;Else, return.
  1183. CK_ROW:        CMP    ROW,24                 ;Are we at last row?
  1184.                JB     INC_ROW                ;If no, increment row.
  1185.                CALL   DN_PG                  ;Else, page down.
  1186.                MOV    ROW,-1                 ;And move row to top.
  1187. INC_ROW:       INC    ROW
  1188.                CLC
  1189. DN_LINE_END:   RET
  1190.  
  1191. UP_PG:         CMP    BP,PAGES               ;Are we already at first page?
  1192.                JNZ    DEC_PG                 ;If no, decrement page.
  1193.                CMP    ROW,0                  ;Are we at first row?
  1194.                STC
  1195.                JZ     UP_PG_END              ;If yes, no update.
  1196.                MOV    ROW,0                  ;Else move to first row.
  1197.                JMP    SHORT UPDATE_PAGE
  1198. DEC_PG:        MOV    SI,LAST_PAGE           ;Get current page.
  1199.                SUB    SI,DS:[BP]             ;Subtract difference to prev page.
  1200.                CMP    SI,OFFSET FILE_BUFFER  ;Beyond top of buffer?
  1201.                JAE    UP_PG_RET              ;If no, page up.
  1202.                CALL   BACKWARD               ;Else, read in previous 16K
  1203.                JMP    SHORT DEC_PG           ;Try again.
  1204. UP_PG_RET:     DEC    BP
  1205.                DEC    BP                     ;Decrement page pointer.
  1206.                MOV    LAST_PAGE,SI           ;Store new starting position
  1207. UPDATE_PAGE:   CLC
  1208. UP_PG_END:     RET
  1209.  
  1210. DN_PG:         CMP    BP,FILE_BUFFER         ;Out of room for page storage?
  1211.                JAE    NOUPDATE_PG            ;If yes, skip.
  1212.                MOV    SI,LAST_PAGE           ;Else, retrieve current page
  1213.                MOV    DISPLAY_FLAG,0         ;No display.
  1214.                MOV    BH,25                  ;Move up 25 lines.
  1215. NEXT_PAGE:     CALL   LINES
  1216.                DEC    BH
  1217.                JNZ    NEXT_PAGE
  1218.                CALL   CK_FILE_END            ;End of file?
  1219.                JC     NOUPDATE_PG            ;If yes, no update.
  1220. INC_PG:        MOV    DX,LAST_PAGE           ;Else, save current offset.
  1221.                MOV    LAST_PAGE,SI           ;Store new offset.
  1222.                MOV    AX,SI
  1223.                SUB    AX,DX                  ;Get difference between pages.
  1224.                INC    BP                     ;Increment page storage.
  1225.                INC    BP
  1226.                MOV    DS:[BP],AX             ;And store.
  1227.                CLC
  1228. DN_PG_END:     RET
  1229. NOUPDATE_PG:   STC
  1230.                RET
  1231.  
  1232. HOME_FILE:     CALL   UP_PG                  ;Page up until top of file.
  1233.                JNC    HOME_FILE
  1234.                CLC
  1235.                RET
  1236.  
  1237. END_FILE:      CALL   DN_PG                  ;Page down until end of file
  1238.                JNC    END_FILE
  1239.                CLC
  1240.                RET
  1241.  
  1242. ;----------------------------------------------------------------;
  1243. ; This subroutine checks to see if end of file has been reached. ;
  1244. ;----------------------------------------------------------------;
  1245.  
  1246. CK_FILE_END:   CMP    SI,FILE_END
  1247.                JB     NOT_FILE_END
  1248.                CMP    FILE_END,OFFSET FILE_BUFFER+(SIXTEEN_K * 2)
  1249.                JAE    NOT_FILE_END
  1250.                STC
  1251.                RET
  1252. NOT_FILE_END:  CLC
  1253.                RET
  1254.  
  1255. ;----------------------------------------------------------------;
  1256. ; This subroutine formats the text into lines.  A line is marked ;
  1257. ; by either a carriage return or reaching the last column (80).  ;
  1258. ;----------------------------------------------------------------;
  1259.  
  1260. LINES:         MOV    CX,80                  ;80 COLUMES
  1261. NEXT_LINES:    CMP    SI,FILE_END            ;If end of file, pad with spaces.
  1262.                JB     GET_LINES
  1263.                CMP    FILE_END,OFFSET FILE_BUFFER+ (SIXTEEN_K * 2)
  1264.                JB     PAD_SPACES
  1265.                PUSH   BX                     ;If end of buffer, save
  1266.                PUSH   CX                     ; our pointers and
  1267.                PUSH   DI                     ; read next 16K.
  1268.                CALL   FORWARD
  1269.                POP    DI                     ;Restore pointers.
  1270.                POP    CX
  1271.                POP    BX
  1272.  
  1273. GET_LINES:     LODSB                         ;Get a byte.
  1274.                CMP    EBCDIC_FLAG,1          ;EBCDIC ON
  1275.                JNE    NOT_EBCDIC             ;NO
  1276. CALL_EBCDIC:   CALL   EBCDIC_TRANS
  1277. NOT_EBCDIC:    AND    AL,WORDSTAR_BIT        ;Strip high bit for WordStar?
  1278.                CMP    AL,13                  ;Carriage return?
  1279.                JZ     PAD_SPACES             ;If yes, pad balance of line
  1280.                CMP    AL,9                   ;Is it tab character?
  1281.                JZ     TAB                    ;If yes, tab.
  1282.                CMP    AL,10                  ;Is it linefeed?
  1283.                JZ     NEXT_LINES             ;If yes, skip.
  1284.                PUSH   CX                     ;Save counter.
  1285.                MOV    CX,1                   ;Else, display one character
  1286.                CALL   CK_DISPLAY
  1287.                POP    CX
  1288. NEXT_BYTES:    LOOP   NEXT_LINES             ;Get next byte.
  1289.                CMP    BYTE PTR [SI],13       ;Is this a eighty column line?
  1290.                JNZ    END_LINES              ;If no, skip.
  1291.                INC    SI                     ;Else, bump pointer past CR.
  1292. END_LINES:     RET
  1293.  
  1294. TAB:           PUSH   CX                     ;Save counter.
  1295.                DEC    CX                     ;Adjust column counter.
  1296.                AND    CX,7                   ;Get bottom three bits.
  1297.                INC    CX                     ;Adjust.
  1298.                PUSH   CX
  1299.                CALL   PAD_SPACES             ;Move to next tab position.
  1300.                POP    AX
  1301.                POP    CX
  1302.                SUB    CX,AX                  ;Adjust counter.
  1303.                JNZ    NEXT_LINES             ;Next byte if not column 80.
  1304.                RET
  1305.  
  1306. PAD_SPACES:    MOV    AL,32                  ;Space character.
  1307. CK_DISPLAY:    CMP    DISPLAY_FLAG,1         ;Are we to write it to screen?
  1308.                JNZ    CK_DISP_END            ;If no, return.
  1309.                MOV    BL,AL
  1310. WRITE_VIEW:    CALL   WRITE_SCREEN           ;Else, write CX spaces.
  1311.                LOOP   WRITE_VIEW
  1312. CK_DISP_END:   RET
  1313.  
  1314. ;-------------------------------------------------------------------;
  1315. ; These two subroutines read either the next or previous 16K bytes. ;
  1316. ;-------------------------------------------------------------------;
  1317.  
  1318. FORWARD:       SUB    LAST_PAGE,SIXTEEN_K    ;Adjust current page offset.
  1319.                XOR    CX,CX                  ;Move file pointer
  1320.                MOV    DX,SIXTEEN_K           ; forward 16K.
  1321.                CALL   MOVE_POINTER
  1322. FIRST_READ:    MOV    SI,OFFSET FILE_BUFFER+SIXTEEN_K
  1323.                MOV    DI,OFFSET FILE_BUFFER  ;Move second half of buffer
  1324.                CALL   MOVE_BUFFER            ; to first half and read 16K
  1325.                MOV    CX,-1                  ;Move file pointer back.
  1326.                NEG    DX
  1327.                CALL   MOVE_POINTER
  1328.                RET
  1329.  
  1330. BACKWARD:      ADD    LAST_PAGE,SIXTEEN_K    ;Adjust current page offset.
  1331.                MOV    CX,-1                  ;Move pointer back 32K.
  1332.                MOV    DX,- (SIXTEEN_K * 2)
  1333.                CALL   MOVE_POINTER
  1334.                MOV    SI,OFFSET FILE_BUFFER            ;Move first half of
  1335.                MOV    DI,OFFSET FILE_BUFFER+SIXTEEN_K  ; buffer to second
  1336.                CALL   MOVE_BUFFER                      ; and read 16K.
  1337.                RET
  1338.  
  1339. MOVE_POINTER:  MOV    BX,FILE_HANDLE
  1340.                MOV    AX,4201H               ;Move file pointer.
  1341.                INT    21H
  1342.                RET
  1343.  
  1344. MOVE_BUFFER:   MOV    DX,SI                  ;Save pointer.
  1345.                MOV    CX,SIXTEEN_K / 2       ;Move 8K words (16K bytes).
  1346.                REP    MOVSW
  1347.                MOV    BX,FILE_HANDLE
  1348.                MOV    CX,SIXTEEN_K           ;Read 16K.
  1349.                MOV    AH,3FH
  1350.                INT    21H
  1351.                MOV    SI,DX
  1352.                MOV    DX,AX
  1353.                ADD    AX,OFFSET FILE_BUFFER+SIXTEEN_K
  1354.                MOV    FILE_END,AX            ;Store end of buffer offset.
  1355.                RET
  1356. ;=======================================================================
  1357.  
  1358. EBCDIC_TRANS:  PUSH   SI
  1359.                MOV    SI,OFFSET EBCDIC_TR           ;LOAD ADDR OF TABLE
  1360.                MOV    AH,0                          ;NEW CHARACTER
  1361.                ADD    SI,AX                         ;ADD CHAR TO ADDR
  1362.                MOV    AL,BYTE PTR[SI]               ;NEW CHARACTER
  1363.                POP    SI
  1364.                RET
  1365.  
  1366. ;---------------------------------------------------;
  1367. ; This subroutine renames the HIGHLIGHED FILES      ;
  1368. ;---------------------------------------------------;
  1369. RENAME:        MOV    RENAME_FILE_FLAG,1           ;TURN RENAME ON
  1370.                CALL   CLEAR_MSG
  1371.                CALL   MOVE                         ;MOVE AND RENAME SAME
  1372.                MOV    RENAME_FILE_FLAG,0           ;TURN RENAME OFF
  1373.                RET
  1374.  
  1375. ;---------------------------------------------------------------;
  1376. ; This subroutine copies either the highlighted or marked file. ;
  1377. ;---------------------------------------------------------------;
  1378. COPY:          CALL   COUNT_MARKS            ;Count marks.
  1379.                CMP    CX,0                   ;Any marked files?
  1380.                JNZ    COPY_DEST              ;If yes, display "Copy" message.
  1381.                CALL   GET_NAME               ;Is the highlighted a directory?
  1382.                JC     COPY_ERROR             ;If yes, exit.
  1383. COPY_DEST:     MOV    DX,172FH
  1384.                MOV    SI,OFFSET COPY_MSG
  1385.                CALL   DISPLAY_TEXT
  1386.                CALL   DESTINATION            ;Ask user for destination.
  1387.                JC     EXIT_COPY               ;If Esc pressed, exit.
  1388.                MOV    COPY_FLAG,1            ;Else, indicate copy.
  1389.                CALL   EXEC_MARKED            ;Execute the command.
  1390.                MOV    COPY_FLAG,0            ;Restore copy flag.
  1391. END_COPY:      MOV    TEMPUS_RETCODE,0        ;SET RETURN CODE
  1392.                CMP    OUTPUT_DIR,00          ;WAS THERE AN OUTPUT ENTERE
  1393.                JE     EXIT_COPY              ;IF NOT EXIT
  1394.                JMP    TERMINATE              ;EXIT TO RN
  1395. EXIT_COPY:     CALL   READ_DIR               ;PUT DIR STUFF IN MEMORY
  1396.                RET
  1397.  
  1398. COPY_ERROR:
  1399.                MOV    TEMPUS_RETCODE,4        ;SET RETURN CODE
  1400.                CALL   BEEP
  1401.                RET
  1402.  
  1403. ;----------------------------------------------------------------;
  1404. ; This subroutine deletes either the highlighted or marked file. ;
  1405. ;----------------------------------------------------------------;
  1406.  
  1407. DELETE:        MOV    DX,172FH               ;Postion cursor for display.
  1408.                CALL   SET_CURSOR
  1409.                CALL   COUNT_MARKS            ;Get count of marked files.
  1410.                CMP    CX,0                   ;Any marked?
  1411.                JNZ    DELETE_MARKED          ;If marked, display number marked.
  1412.                CALL   GET_NAME               ;Else get highlighted.
  1413.                JC     DELETE_ERROR           ;If it's a directory exit.
  1414.                CMP    BYTE PTR [SI+39],"H"   ;If it's a hidden file exit.
  1415.                JZ     DELETE_ERROR
  1416.                MOV    SI,FILE_NAME           ;Else display filename.
  1417.                JMP    SHORT DISP_DELETE
  1418.  
  1419. DELETE_MARKED: MOV    AX,CX                  ;Display count of marked files.
  1420.                CALL   GET_COUNT
  1421.                MOV    SI,OFFSET MARKED_MSG   ;Display "marked files".
  1422. DISP_DELETE:   CALL   GET_TEXT
  1423.                MOV    SI,OFFSET DELETE_MSG   ;Display "will be deleted".
  1424.                CALL   GET_TEXT
  1425.                MOV    DX,182FH               ;Display warning message.
  1426.                CALL   DISPLAY_TEXT
  1427.  
  1428. QUERY:         CALL   READ_KEY               ;Get a keystroke.
  1429.                CMP    AH,31H                 ;Is it "N"?
  1430.                JZ     DELETE_END             ;If yes, exit delete.
  1431.                CMP    AH,1                   ;Is it Esc?
  1432.                JZ     DELETE_END             ;If yes, exit delete.
  1433.                CMP    AH,15H                 ;Is it "Y"?
  1434.                JZ     DELETE_FILE            ;If yes, delete
  1435.                CALL   BEEP                   ;Else, beep.
  1436.                JMP    SHORT QUERY            ;And get another keystroke.
  1437.  
  1438. DELETE_FILE:   MOV    DELETE_FLAG,1          ;Indicate deletion.
  1439.                CALL   EXEC_MARKED            ;Execute the command.
  1440.                MOV    DELETE_FLAG,0          ;Restore deletion flag.
  1441. DELETE_END:    CALL   CLEAR_MSG
  1442.                RET
  1443.  
  1444. DELETE_ERROR:  CALL   BEEP                   ;Beep if error.
  1445.                RET
  1446.  
  1447. ;--------------------------------------------------------------;
  1448. ; This subroutine moves either the highlighted or mark ed file.;
  1449. ;--------------------------------------------------------------;
  1450.  
  1451. MOVE:          CALL   COUNT_MARKS            ;Get count of marked files.
  1452.                CMP    CX,0                   ;Any files marked?
  1453.                JNZ    MOVE_DEST              ;If yes, display message.
  1454.                CALL   GET_NAME               ;Else, see if highlighted is a
  1455.                JC     MOVE_ERROR             ; directory; If yes, exit.
  1456. MOVE_DEST:     MOV    DX,172FH
  1457.                MOV    SI,OFFSET MOVE_MSG     ;Display move message.
  1458.                CMP    RENAME_FILE_FLAG,1
  1459.                JNZ    MOVE_MSG_WRIT
  1460.                MOV    SI,OFFSET RENAME_MSG   ;Display RENAME MESSAGE
  1461. MOVE_MSG_WRIT: CALL   DISPLAY_TEXT
  1462.                CALL   DESTINATION            ;Get user response.
  1463.                JC     END_MOVE               ;If Esc pressed, exit.
  1464.                MOV    AL,CURRENT_DISK        ;Else, check if move across drives.
  1465.                ADD    AL,"A"                 ;Get default drive.
  1466.                CMP    BYTE PTR ENTRY B + 1,":"  ;Is there a drive specified?
  1467.                JNZ    CK_DRIVE                 ;If not, use default.
  1468.                MOV    AL,ENTRY B             ;Else, use user drive.
  1469.                AND    AL,5FH                 ;Capitalize.
  1470. CK_DRIVE:      CMP    AL,SOURCE B            ;Is it the same as source?
  1471.                JZ     JUST_RENAME            ;If yes, rename.
  1472. COPY_DELETE:   MOV    COPY_FLAG,1            ;Else, indicate both copy/delete.
  1473.                MOV    DELETE_FLAG,1
  1474. JUST_RENAME:   MOV    RENAME_FLAG,1
  1475. EXEC_MOVE:     CALL   EXEC_MARKED            ;Execute the command.
  1476. END_MOVE:      MOV    DELETE_FLAG,0          ;Restore all flags.
  1477.                MOV    COPY_FLAG,0
  1478.                CMP    RENAME_FLAG,1
  1479.                JNE    NO_REREAD
  1480. NO_REREAD:     MOV    RENAME_FLAG,0
  1481.                MOV    TEMPUS_RETCODE,0        ;SET RETURN CODE
  1482.                CMP    OUTPUT_DIR,00          ;WAS THERE AN OUTPUT ENTEREd
  1483.                JE     EXIT_MOVE              ;IF NOT EXIT
  1484.                JMP    TERMINATE              ;EXIT TO RN
  1485. EXIT_MOVE:     CALL   READ_DIR               ;PUT DIR STUFF IN MEMORY
  1486.                RET
  1487.  
  1488. MOVE_ERROR:    MOV    TEMPUS_RETCODE,4        ;SET RETURN CODE
  1489.                CALL   BEEP
  1490.                RET
  1491.  
  1492. ;-----------------------------------;
  1493. ; This subroutine clears all marks. ;
  1494. ;-----------------------------------;
  1495.  
  1496. CLEAR_MARK:    MOV    SI,OFFSET BUFFER       ;Point to start of listing.
  1497. NEXT_CLEAR:    MOV    BYTE PTR [SI],32       ;Write space over mark.
  1498.                ADD    SI,FIELD_SIZE          ;Next record.
  1499.                CMP    SI,END_OFFSET          ;End of listing?
  1500.                JB     NEXT_CLEAR             ;If no, continue until done.
  1501.                RET
  1502. ;----------------------------------------------------------------------;
  1503. ; This subroutine marks all files that aren't marked with an asterisk. ;
  1504. ;----------------------------------------------------------------------;
  1505.  
  1506. MARK_BLANK:    MOV    SI,OFFSET BUFFER       ;Point to start of listing.
  1507. NEXT_BLANK:    CMP    BYTE PTR [SI+14],"<"   ;Is it a directory?
  1508.                JZ     LOOP_MARK              ;If yes, skip.
  1509.                CMP    BYTE PTR [SI+40],"H"   ;Is it a hidden file?
  1510.                JZ     LOOP_MARK              ;If yes, skip.
  1511.                CMP    BYTE PTR [SI],32       ;Is it blank (a space)?
  1512.                JNZ    LOOP_MARK                 ;If no, skip.
  1513.                MOV    BYTE PTR [SI],COPY_MARK   ;Else mark.
  1514. LOOP_MARK:     ADD    SI,FIELD_SIZE             ;Next record.
  1515.                CMP    SI,END_OFFSET          ;Continue until done.
  1516.                JB     NEXT_BLANK
  1517.                RET
  1518.  
  1519. ;--------------------------------------------------------;
  1520. ; This subroutine marks or unmarks the highlighted file. ;
  1521. ;--------------------------------------------------------;
  1522. MARK_UNMARK:   MOV    DL,"?"                 ;SPECIAL MARK
  1523.                JMP    SHORT STORE_MARK
  1524.  
  1525. MARK:          MOV    DL,COPY_MARK           ;Right arrow character.
  1526.                JMP    SHORT STORE_MARK
  1527.  
  1528. UNMARK:        MOV    DL,32                  ;Space character.
  1529.  
  1530. STORE_MARK:    CALL   GET_NAME               ;Get filename.
  1531.                JC     MARK_END               ;If directory, skip.
  1532.                CMP    BYTE PTR [SI+39],"H"   ;Is it a hidden file?
  1533.                JZ     MARK_END               ;If yes, skip.
  1534.                CMP    DL,"?"                 ;IS IT ? FOR ON/OFF
  1535.                JNZ    SHORT MARK_ON_OFF      ;NOT = GO DO MARK
  1536.                CMP    BYTE PTR [SI-1],COPY_MARK ;IS IT MARKED
  1537.                JNZ    MARK_ONE               ;NO GO MARK IT
  1538.                MOV    BYTE PTR [SI-1],32     ;TURN MARK OFF
  1539.                JMP    SHORT MARK_END         ;TO END
  1540. MARK_ONE:      MOV    BYTE PTR [SI-1],COPY_MARK ;MARK IT
  1541.                JMP    SHORT MARK_END         ;TO END
  1542. MARK_ON_OFF:   MOV    [SI-1],DL              ;Else store the character.
  1543. MARK_END:      CALL   DN_ARROW2              ;And move down a row.
  1544.                RET
  1545. ;------------------------------------------------;
  1546. ; This subroutine toggles the copy verify state. ;
  1547. ;------------------------------------------------;
  1548.  
  1549. VERIFY:        XOR    VERIFY_FLAG,1               ;Toggle flag.
  1550.                MOV    AL,1                        ;ASSUME ON
  1551.                MOV    SI,OFFSET VERIFY_ON B
  1552.                MOV    BYTE PTR [SI],251
  1553.  
  1554.                CMP    VERIFY_FLAG,1               ;Is it on?
  1555.                JZ     TOGGLE                      ;If yes, store.
  1556.                XOR    AL,AL
  1557.                MOV    BYTE PTR [SI],32
  1558.  
  1559. TOGGLE:        CALL   SET_VERIFY
  1560.                CALL   REFRESH_MENU                ;Display.
  1561.                RET
  1562. ;------------------------------------------------;
  1563. ; This subroutine toggles to EBCDIC mode.        ;
  1564. ;------------------------------------------------;
  1565.  
  1566. EBCDIC:        XOR    EBCDIC_FLAG,1               ;Toggle flag.
  1567.                MOV    SI,OFFSET EBCDIC_ON B
  1568.                MOV    BYTE PTR [SI],251           ;ASSUME ON
  1569.                CMP    EBCDIC_FLAG,1               ;Is it on?
  1570.                JE     EBCDIC_TOGGLE
  1571.                MOV    BYTE PTR [SI],32            ;TURNMOFFN
  1572. EBCDIC_TOGGLE: CALL   REFRESH_MENU                ;Display.
  1573.                RET
  1574.  
  1575. ;--------------------------------------------------;
  1576. ; This subroutine toggles the toggle wordstar mode ;
  1577. ;--------------------------------------------------;
  1578.  
  1579. WORDSTAR:      XOR    WORDSTAR_BIT,80H            ;Toggle flag.
  1580.                MOV    SI,OFFSET WORDSTAR_ON B
  1581.                MOV    BYTE PTR [SI],251           ;ASSUME ON
  1582.                CMP    WORDSTAR_BIT,7FH            ;Is it on?
  1583.                JE     WORDSTAR_TOGGLE             ;If yes, store.
  1584.                MOV    BYTE PTR [SI],32            ;TURN OFF
  1585.  
  1586. WORDSTAR_TOGGLE: CALL   REFRESH_MENU                ;Display.
  1587.                RET
  1588. ;----------------------------------------------------;
  1589. ; This subroutine counts the number of marked files. ;
  1590. ;----------------------------------------------------;
  1591.  
  1592. COUNT_MARKS:   XOR    CX,CX                  ;Zero out counter.
  1593.                MOV    SI,OFFSET BUFFER          ;Point to start of listing.
  1594. NEXT_COPY:     CMP    BYTE PTR [SI],COPY_MARK   ;Is it marked?
  1595.                JNZ    LOOP_COPY                 ;In no, skip.
  1596.                INC    CX                     ;Else, increment counter.
  1597. LOOP_COPY:     ADD    SI,FIELD_SIZE          ;Next record.
  1598.                CMP    SI,END_OFFSET          ;Continue until done.
  1599.                JB     NEXT_COPY
  1600.                MOV    MARK_CNT,CX            ;Store the count of marked files.
  1601.                RET
  1602.  
  1603. ;---------------------------------------------;
  1604. ; This subroutine prompts the user for the    ;
  1605. ; destination of highlighted or marked files. ;
  1606. ;---------------------------------------------;
  1607.  
  1608. DESTINATION:   CALL   GET_NAME               ;Get filename.
  1609.                MOV    SI,FILE_NAME
  1610.                MOV    AX,MARK_CNT            ;Retrieve count of marked files.
  1611.                CMP    AX,0                   ;Were there any?
  1612.                JZ     DISP_SOURCE            ;If no, display source filename.
  1613.                CALL   GET_COUNT              ;Else, display count of marked.
  1614.                MOV    SI,OFFSET MARKED_MSG   ;Display "marked files".
  1615. DISP_SOURCE:   CALL   GET_TEXT
  1616. ;-----------------------FW CHANGE-------------------------------------
  1617.                CMP    OUTPUT_DIR,00          ;WAS THERE AN OUTPUT ENTEREd
  1618.                JZ     COPY_DO_MSG
  1619.                CALL   CLEAR_OLD              ;CLEAR LAST ENTRY
  1620.                MOV    SI,OFFSET OUTPUT_DIR
  1621.                MOV    DI,OFFSET ENTRY B      ;Write OUTPUT DIR
  1622.                XOR    AX,AX
  1623.                MOV    CX,LGTH_DIR
  1624.                REP    MOVSB
  1625.                JMP    DO_DEST                ;If yes, execute.
  1626. COPY_DO_MSG:   MOV    SI,OFFSET TO_MSG       ;Display "to..."
  1627. ;---------------=-----------------------------------------------------
  1628.                CALL   GET_TEXT
  1629.                MOV    DX,182FH
  1630.                CALL   CLEAR_OLD              ;Remove last user entry.
  1631.  
  1632. GET_DEST:      CALL   READ_KEY               ;Get a keystroke.
  1633.                CMP    AL,27                  ;Is it Esc?
  1634.                JZ     ABORT_DEST             ;If yes, abort.
  1635.                CMP    AL,13                  ;Is it carriage return?
  1636.                JZ     DO_DEST                ;If yes, execute.
  1637.                CMP    AL,8                   ;Is it backspace?
  1638.                JNZ    NOT_BS3                ;If yes, backspace.
  1639.                CALL   MOVE_BS
  1640.                JMP    SHORT GET_DEST
  1641. NOT_BS3:       CMP    AL,32                  ;Is it above space?
  1642.                JBE    GET_DEST               ;If no, ignore.
  1643.                CMP    DI,OFFSET ENTRY B + 32  ;Else, is 32 line entry field full?
  1644.                JZ     GET_DEST               ;If yes, ignore.
  1645.                STOSB                         ;Else, store the character.
  1646.                CALL   WRITE_TEXT             ;And display it.
  1647.                JMP    SHORT GET_DEST
  1648. ABORT_DEST:    CALL   CURSOR_OFF
  1649.                CALL   CLEAR_MSG
  1650.                STC
  1651.                RET
  1652.  
  1653. DO_DEST:       CLC
  1654.                RET
  1655.  
  1656. ;------------------------------------------------------------------------------;
  1657. ; This subroutine either copies moves or deletes a highlighted or marked file. ;
  1658. ;------------------------------------------------------------------------------;
  1659.  
  1660. EXEC_MARKED:
  1661.                CLC
  1662.                CALL   CURSOR_OFF             ;Turn cursor off.
  1663.                CMP    MARK_CNT,0             ;Are there any files marked?
  1664.                JNZ    MANY_MARKS             ;If yes, go find them.
  1665.                MOV    MARK_CNT,1             ;Else, change loop counter to one.
  1666.                CALL   GET_NAME
  1667.                JMP    SHORT EXEC_BAR         ;And execute it one time.
  1668.  
  1669. MANY_MARKS:    CALL   HOME_BAR               ;Home the highlight bar.
  1670. CK_MARK:       CALL   UPDATE_SCREEN          ;Update the screen.
  1671.                CALL   GET_NAME                   ;Get the highlighted filename.
  1672.                CMP    BYTE PTR [SI-1],COPY_MARK  ;Is it marked?
  1673.                JZ     EXEC_BAR                   ;If yes, execute command
  1674.                CALL   DN_ARROW2              ;Else, move down a row.
  1675.                JMP    SHORT CK_MARK          ;And check it for a mark.
  1676.  
  1677. EXEC_BAR:      CMP    BYTE PTR [SI+39],"H"   ;Is it a hidden file?
  1678.                JZ     EXEC_ERROR             ;If yes, skip.
  1679.                CMP    RENAME_FLAG,1          ;Is it a same drive move?
  1680.                JNZ    CK_COPY                ;If no, skip renaming.
  1681.                CALL   PARSE_ENTRY            ;Else, parse user entry.
  1682.                MOV    DX,OFFSET TARGET       ;Point to target.
  1683.                MOV    CX,7                   ;Does the file exist?
  1684.                CALL   FIND_FIRST
  1685.                JNC    EXEC_ERROR             ;If yes, skip
  1686.                CMP    COPY_FLAG,1            ;Is it across drives?
  1687.                JZ     GO_READ_WRITE          ;Is yes copy/delete.
  1688.                MOV    DX,OFFSET SOURCE B
  1689.                MOV    DI,OFFSET TARGET
  1690.                MOV    AH,56H                 ;Else, rename it.
  1691.                INT    21H
  1692.                JC     EXEC_ERROR             ;Next one if failed.
  1693.                JMP    SHORT REMOVE           ;Else, remove it from list.
  1694.  
  1695. CK_COPY:       CMP    COPY_FLAG,1            ;Is it a copy request?
  1696.                JNZ    CK_DELETE              ;If no, check delete.
  1697.                CALL   PARSE_ENTRY            ;Else parse user entry.
  1698. GO_READ_WRITE: CALL   READ_WRITE             ;Copy the file.
  1699.                JC     EXEC_ERROR             ;If failed, skip rest.
  1700. MARK_IT:       MOV    SI,CUR_FILE            ;Else, mark with PERIOD
  1701.                MOV    BYTE PTR [SI-1],COPY_MARK_DONE
  1702. CK_DELETE:     CMP    DELETE_FLAG,1          ;Is it a delete request?
  1703.                JNZ    CK_KEYSTROKE           ;If no, skip.
  1704.                MOV    DX,OFFSET SOURCE B     ;Else, delete the file.
  1705.                MOV    AH,41H
  1706.                INT    21H
  1707.                JC     EXEC_ERROR
  1708. REMOVE:        CALL   REMOVE_FILE            ;If successful, remove from list.
  1709.                JMP    SHORT CK_KEYSTROKE
  1710.  
  1711. EXEC_ERROR:    CALL   BEEP
  1712.                MOV    ERROR_EXEC,1
  1713.                CALL   DN_ARROW2              ;Go to next line.
  1714.  
  1715. CK_KEYSTROKE:  CALL   CK_KEY                 ;Was a key struck while busy
  1716.                JNZ    CLEAR_KEY              ; at our copy, move or delete task?
  1717.                DEC    MARK_CNT               ;If yes, abort, else all done?
  1718.                JZ     END_EXEC               ;If no, continue until done.
  1719.                JMP    CK_MARK
  1720.  
  1721. CLEAR_KEY:     CALL   READ_KEY               ;Clear the keyboard buffer,
  1722.                CALL   CK_KEY                 ; user entry and prompt.
  1723.                JNZ    CLEAR_KEY
  1724. END_EXEC:      CALL   UPDATE_FREE
  1725.                CALL   FILE_COUNT
  1726.                CALL   CLEAR_MSG
  1727.                RET
  1728.  
  1729. ;----------------------------------------;
  1730. ; This subroutine parses the user entry. ;
  1731. ;----------------------------------------;
  1732.  
  1733. PARSE_ENTRY:   MOV    BP,OFFSET TARGET       ;Point to target storage.
  1734.                MOV    DI,BP
  1735.                MOV    SI,OFFSET ENTRY B      ;Point to user entry.
  1736.                CMP    BYTE PTR [SI],0        ;Anything entered?
  1737.                JNZ    GET_END                ;If yes, continue.
  1738.                JMP    TACK_FILENAME          ;Else, store source name.
  1739.  
  1740. GET_END:       LODSB                         ;Move user entry into target
  1741.                STOSB                         ; workspace.
  1742.                CMP    AL,0
  1743.                JNZ    GET_END
  1744.  
  1745.                STD                           ;Reverse string operation.
  1746.                DEC    DI                     ;Adjust pointer back one.
  1747.                MOV    SI,DI                  ;Make it the source pointer.
  1748.                MOV    FILENAME_END,DI        ;And store.
  1749. FIND_PATH:     CMP    SI,OFFSET TARGET - 1   ;Are we at start of name?
  1750.                JZ     SEARCH_WILD            ;If yes, done here.
  1751.                LODSB
  1752.                CMP    AL,"\"                 ;Else, is it a path delimiter?
  1753.                JZ     FOUND_PATH             ;If yes, mark start of filename.
  1754.                CMP    AL,":"                 ;Colon is also a path delimiter.
  1755.                JNZ    FIND_PATH
  1756.  
  1757. FOUND_PATH:    INC    SI                     ;Adjust pointer to end of path.
  1758. SEARCH_WILD:   INC    SI
  1759.                MOV    BP,SI                  ;And store.
  1760.                CLD                           ;String back to forward.
  1761.                MOV    DI,FCB                 ;Use file control block for
  1762.                MOV    AX,2900H               ; workspace.
  1763.                INT    21H                    ;Parse the entry for globals.
  1764.                CMP    AL,1                   ;Any wild cards?
  1765.                JNZ    CK_PATH                ;If no, check if it's a directory.
  1766.  
  1767.                MOV    SI,FCB + 1             ;Else, point to first character.
  1768.                MOV    DI,BP                  ;Point to target storage.
  1769.                MOV    BX,FILE_NAME           ;Point to source.
  1770.                MOV    CX,8                   ;Eight characters.
  1771. GLOBAL_NAME:   LODSB
  1772.                CMP    AL,32                  ;End of name?
  1773.                JZ     EXTENSION              ;If yes, do extension.
  1774.                CMP    AL,"?"                 ;Wild card?
  1775.                JNZ    LOOP_NAME              ;If no, store target character.
  1776.                MOV    AL,[BX]                ;Else, replace with source char.
  1777.                CMP    AL,"."                 ;Unless end of name.
  1778.                JZ     EXTENSION
  1779.                CMP    AL,0
  1780.                JZ     EXTENSION
  1781. LOOP_NAME:     STOSB                         ;Store the character.
  1782.                CMP    BYTE PTR [BX],"."      ;Are we at end of source name?
  1783.                JZ     NEXT_GLOBAL            ;If yes, don't move pointer.
  1784.                INC    BX                     ;Else, point to next source char.
  1785. NEXT_GLOBAL:   LOOP   GLOBAL_NAME
  1786.  
  1787. EXTENSION:     MOV    AL,"."                 ;Filename delimiter.
  1788.                STOSB                         ;Store it.
  1789. FIND_EXT:      CMP    [BX],AL                ;Was there a dot in source?
  1790.                JZ     DO_DOT                 ;If yes do extension.
  1791.                CMP    BYTE PTR [BX],0        ;End of source name?
  1792.                JZ     DO_EXT                 ;If yes, do extension.
  1793.                INC    BX                     ;Else, go to end of name.
  1794.                JMP    SHORT FIND_EXT
  1795.  
  1796. DO_DOT:        INC    BX                     ;Bump pointer past dot.
  1797. DO_EXT:        MOV    SI,FCB + 9             ;Point to extension of parsed.
  1798.                MOV    CX,3                   ;Three characters.
  1799. DO_EXTENSION:  LODSB
  1800.                CMP    AL,32                  ;End of parsed?
  1801.                JZ     END_GLOBAL             ;If yes, done here.
  1802.                CMP    AL,"?"                 ;Wild card?
  1803.                JNZ    LOOP_EXT               ;If no, store user character.
  1804.                MOV    AL,[BX]                ;Else, store source character.
  1805.  
  1806. LOOP_EXT:      STOSB
  1807.                INC    BX
  1808.                LOOP   DO_EXTENSION           ;Do all three extension chars.
  1809.  
  1810. END_GLOBAL:    XOR    AL,AL                  ;Make it an ASCIIZ.
  1811.                STOSB
  1812.                JMP    SHORT PARSE_END        ;Done here.
  1813.  
  1814. CK_PATH:       MOV    DI,BP                  ;Any characters after path
  1815.                CMP    BP,FILENAME_END        ; delimiter?
  1816.                JZ     TACK_FILENAME          ;If no, tack on source name.
  1817.                MOV    DX,OFFSET ENTRY B      ;Else, see if it's a directory.
  1818.                MOV    CX,10H
  1819.                CALL   FIND_FIRST
  1820.                JC     PARSE_END              ;If not found, done here.
  1821.                CMP    DS:[149],CL            ;If not directory, done here.
  1822.                JNZ    PARSE_END
  1823.                MOV    DI,FILENAME_END        ;Else, tack on source filename.
  1824.                MOV    AL,"\"
  1825.                STOSB
  1826.  
  1827. TACK_FILENAME: MOV    SI,FILE_NAME           ;Source filename.
  1828.                MOV    CX,7
  1829.                REP    MOVSW
  1830. PARSE_END:     RET
  1831.  
  1832. ;----------------------------------------------------;
  1833. ; This section does the reading and writing to disk. ;
  1834. ;----------------------------------------------------;
  1835.  
  1836. READ_WRITE:    MOV    DX,OFFSET SOURCE B     ;Point to source filespec.
  1837.                XOR    AL,AL                  ;Open file for reading.
  1838.                CALL   OPEN_FILE
  1839.                JNC    SAVE_HANDLE
  1840.                JMP    END_RW                 ;Exit if failed.
  1841. SAVE_HANDLE:   MOV    READ_HANDLE,AX         ;Save the handle.
  1842.                MOV    CX,7
  1843.                CALL   FIND_FIRST             ;Get source
  1844.                MOV    SI,149
  1845.                LODSB
  1846.                XOR    AH,AH
  1847.                MOV    SOURCE_ATTRIB,AX       ; attribute
  1848.                MOV    TARGET_ATTRIB,AX       ; attribute
  1849.                LODSW
  1850.                MOV    SOURCE_TIME,AX         ; time
  1851.                LODSW
  1852.                MOV    SOURCE_DATE,AX         ; date
  1853.                LODSW
  1854.                MOV    SIZE_LOW,AX            ; and size
  1855.                LODSW
  1856.                MOV    SIZE_HIGH,AX           ; and save.
  1857.  
  1858.                MOV    DX,OFFSET TARGET       ;Point to target filename.
  1859.                CALL   FIND_FIRST             ;Does it exist?
  1860.                JNC    CK_IF_SAME             ;If yes, see if same as source.
  1861.  
  1862.                CALL   GET_DISK               ;Else, get disk free space.
  1863.                JMP    SHORT CK_FREE          ;Go see if enough room.
  1864.  
  1865. CK_IF_SAME:    MOV    CL,DS:[149]            ;Get attribute of target
  1866.                XOR    CH,CH
  1867.                MOV    BP,CX                  ; and save.
  1868.                XOR    CX,1                   ;Flip read-only attribute.
  1869.                CALL   CHMOD
  1870.                MOV    DX,OFFSET SOURCE B     ;Now get source attribute.
  1871.                CALL   GETMOD
  1872.                CMP    CX,SOURCE_ATTRIB       ;See if it has changed.
  1873.                PUSHF                         ;Save compare results.
  1874.                MOV    DX,OFFSET TARGET       ;Restore target attribute.
  1875.                MOV    CX,BP
  1876.                CALL   CHMOD
  1877.                POPF                          ;Retrieve compare results.
  1878.                STC                           ;Assume files are the same.
  1879.                JZ     GET_FREE_SPACE
  1880.                JMP    CLOSE_READ             ;If they are, exit.
  1881. GET_FREE_SPACE: CALL   GET_DISK               ;Else, get free disk space.
  1882.                ADD    AX,DS:[154]
  1883.                ADC    DX,DS:[156]            ;Target size + disk free.
  1884. CK_FREE:       SUB    AX,SIZE_LOW            ;Total - source size.
  1885.                SBB    DX,SIZE_HIGH
  1886.                JB     CLOSE_READ             ;If negative, not enough room.
  1887.  
  1888. CREATE:        MOV    DX,OFFSET TARGET       ;Create and truncate target file
  1889.                XOR    CX,CX                  ; to zero.
  1890.                MOV    CX,TARGET_ATTRIB       ;attribute
  1891.                MOV    AH,3CH
  1892.                INT    21H
  1893.                JC     CLOSE_READ
  1894.                MOV    WRITE_HANDLE,AX        ;Save handle.
  1895.                MOV    AX,DS                  ;Point to second 64K segment
  1896.                ADD    AX,1000H               ; for read/write buffer.
  1897.                MOV    DS,AX
  1898.                XOR    DX,DX
  1899.  
  1900. COPY_READ:     MOV    BX,CS:READ_HANDLE      ;Retrieve read handle.
  1901.                MOV    CX,0FFFFH              ;Read up to 64K at a time.
  1902.                MOV    AH,3FH
  1903.                INT    21H
  1904.                JC     COPY_DONE              ;If done, exit.
  1905.                CMP    AX,0                   ;If zero, also done.
  1906.                JZ     CHANGE_DATE
  1907.  
  1908.                MOV    BP,AX                  ;Save bytes read.
  1909.                MOV    CX,AX                  ;Bytes read into counter.
  1910.                MOV    BX,CS:WRITE_HANDLE     ;Retrieve write handle.
  1911.                MOV    AH,40H
  1912.                INT    21H                    ;Write the buffer to disk.
  1913.                JC     COPY_DONE
  1914.                CMP    CX,BP                  ;Did we write same number as read?
  1915.                STC                           ;Assume we had a problem.
  1916.                JNZ    COPY_DONE              ;If no, exit.
  1917.                CMP    CX,0FFFFH              ;Was it a full 64K read?
  1918.                JZ     COPY_READ              ;If yes, there must be more.
  1919. CHANGE_DATE:   MOV    BX,CS:WRITE_HANDLE
  1920.                MOV    CX,CS:SOURCE_TIME      ;Else, make time/date same
  1921.                MOV    DX,CS:SOURCE_DATE      ; as source.
  1922.                MOV    AX,5701H
  1923.                INT    21H
  1924.  
  1925. COPY_DONE:     PUSH   CS                     ;Restore data segment.
  1926.                POP    DS
  1927.  
  1928. CLOSE_WRITE:   PUSHF                         ;Save error if any.
  1929.                MOV    BX,WRITE_HANDLE        ;Close write file.
  1930.                CALL   CLOSE_FILE
  1931. ;---------------FW MOD--------------------------------------------------
  1932.                CMP    OUTPUT_DIR,00          ;WAS THERE AN OUTPUT ENTERE
  1933.                JE     CLOSE_COMP
  1934.                XOR    CX,CX                  ; ATTRIBUTE TP 00
  1935.                MOV    DX,OFFSET TARGET       ;POINT AT TARGET
  1936.                CALL   CHMOD
  1937. ;-----------------------------------------------------------------------
  1938. CLOSE_COMP:    POP    AX                     ;Retrieve flags.
  1939.                JC     CLOSE_READ             ;Close successful?
  1940.                XCHG   AH,AL                  ;If no, exit with error, else
  1941.                SAHF                          ; retrieve write state.
  1942.  
  1943. CLOSE_READ:    PUSHF                         ;Save flags.
  1944.                MOV    BX,READ_HANDLE         ;Close read file.
  1945.                CALL   CLOSE_FILE             ;Return with status of
  1946.                POPF                          ; write file.
  1947. END_RW:        RET
  1948.  
  1949. ;------------------------------------------------------------------------;
  1950. ; These four subroutines control in which column the sorting will start. ;
  1951. ;------------------------------------------------------------------------;
  1952. SORT_TYPE:     MOV    DX,162FH               ;Postion cursor for display.
  1953.                MOV    SI,OFFSET SORT_MSG1    ;ENTER
  1954.                CALL   DISPLAY_TEXT
  1955.                MOV    DX,172FH               ;Display warning message.
  1956.                MOV    SI,OFFSET SORT_MSG2    ;TYPE OF SORT
  1957.                CALL   DISPLAY_TEXT
  1958.                MOV    DX,182FH               ;Display warning message.
  1959.                CALL   SET_CURSOR
  1960.  
  1961.                CALL   READ_KEY               ;Get a keystroke.
  1962.                MOV    SAVE_KEY,AH            ;SAVE KEY
  1963.                CALL   CLEAR_MSG
  1964.                MOV    AH,SAVE_KEY
  1965.                CMP    AH,K_N                 ;Is it "N"AME
  1966.                JZ     SORT_NAME
  1967.                CMP    AH,K_E                 ;Is it "E"XTENSION
  1968.                JZ     SORT_EXT
  1969.                CMP    AH,K_S                 ;Is it "S"IZE
  1970.                JZ     SORT_SIZE
  1971.                CMP    AH,K_D                 ;Is it "D"ATE
  1972.                JZ     SORT_DATE
  1973.                CMP    AH,K_T                 ;Is it "T"IME
  1974.                JZ     SORT_DATE
  1975.                RET
  1976. ;------------------------------------------------------------------------;
  1977.  
  1978. SORT_NAME:     MOV    SORT_OFFSET,0
  1979.                JMP    SHORT SORT_MSG
  1980.  
  1981. SORT_EXT:      MOV    SORT_OFFSET,4
  1982.                JMP    SHORT SORT_MSG
  1983.  
  1984. SORT_SIZE:     MOV    SORT_OFFSET,8
  1985.                JMP    SHORT SORT_MSG
  1986.  
  1987. SORT_DATE:     MOV    SORT_OFFSET,12
  1988. SORT_MSG:      MOV    DX,1733H
  1989.                MOV    SI,OFFSET LOADING+12
  1990.                CALL   DISPLAY_TEXT
  1991.  
  1992. ;------------------------------------------;
  1993. ; This subroutine does the actual sorting. ;
  1994. ;------------------------------------------;
  1995.  
  1996. SORT:          CMP    COUNT,1                ;Can't sort one file.
  1997.                JZ     SORT_RETURN
  1998.                MOV    DX,END_OFFSET          ;End of filenames in DX.
  1999.                SUB    DX,44
  2000.                MOV    BP,SORT_OFFSET
  2001. NEXT_PASS:     MOV    SORT_FLAG,0
  2002.                MOV    BX,OFFSET BUFFER + 1   ;Point to start of buffer.
  2003.  
  2004. NEXT_SORT:     MOV    SI,BX                  ;Source and destination.
  2005.                ADD    SI,SORT_TABLE[BP]
  2006.                MOV    DI,SI
  2007.                ADD    DI,FIELD_SIZE
  2008.                CMP    BP,12                  ;Is it special case of date?
  2009.                JZ     DO_DATE                ;If yes, go do it.
  2010.                MOV    CX,SORT_TABLE[BP+2]
  2011. COMPARE:       REPZ   CMPSB                  ;Compare filenames.
  2012.                JBE    END_SORT               ;If already in order, skip.
  2013.  
  2014. SWAP:          MOV    SI,BX                  ;Else, recover pointers.
  2015.                DEC    SI
  2016.                MOV    DI,SI
  2017.                ADD    DI,FIELD_SIZE
  2018.                MOV    CX,FIELD_SIZE / 2      ;Exchange the records.
  2019. NEXT_SWAP:     MOV    AX,[DI]
  2020.                MOVSW
  2021.                MOV    [SI-2],AX
  2022.                LOOP   NEXT_SWAP
  2023.                MOV    SORT_FLAG,1            ;Flag that exchange was made.
  2024.  
  2025. END_SORT:      ADD    BX,FIELD_SIZE          ;Point to next record.
  2026.                CMP    BX,DX                  ;End of top?
  2027.                JB     NEXT_SORT              ;If no, bubble sort next.
  2028.                SUB    DX,FIELD_SIZE          ;Else, move top down one record.
  2029.                CMP    SORT_FLAG,0            ;Was there exchange made?
  2030.                JNZ    NEXT_PASS              ;If yes, another pass.
  2031. SORT_RETURN:   CALL   CLEAR_MSG
  2032.                CMP    SORT_OFFSET,12
  2033.                JNE    SORT_EXIT
  2034.                CALL   END_BAR                ;GO TO END IF DATE SORT
  2035. SORT_EXIT:     RET
  2036.  
  2037. DO_DATE:       MOV    CX,2                   ;Compare year first.
  2038.                REPZ   CMPSB
  2039.                JA     SWAP                   ;If above, swap.
  2040.                JNZ    END_SORT
  2041.                SUB    SI,8                   ;Else, adjust and do month/day.
  2042.                SUB    DI,8
  2043.                MOV    CX,5
  2044.                REPZ   CMPSB
  2045.                JA     SWAP                   ;If above, swap.
  2046.                JNZ    END_SORT
  2047.                ADD    SI,10                  ;Else, adjust and do meridian.
  2048.                ADD    DI,10
  2049.                CMPSB
  2050.                JA     SWAP                   ;If above, swap.
  2051.                JNZ    END_SORT
  2052.                SUB    SI,6                   ;Else, adjust and do time.
  2053.                SUB    DI,6
  2054.                MOV    CX,5
  2055.                CMP    WORD PTR [SI],3231H    ;Is it special case "12:"?
  2056.                JZ     CK_MERIDIAN            ;If yes, see if same.
  2057.                CMP    WORD PTR [DI],3231H    ;Is destination "12:"?
  2058.                JNZ    COMPARE                ;If no, normal compare.
  2059.                JMP    SWAP                   ;Else, swap.
  2060. CK_MERIDIAN:   CMPSW                         ;Are both "12:"?
  2061.                JNZ    END_SORT               ;If no, next record.
  2062.                MOV    CX,3                   ;Else compare minutes.
  2063.                JMP    SHORT COMPARE
  2064.  
  2065. ;--------------------------------------------------------------------------;
  2066. ; These six subroutines control the bar and page of the directory listing. ;
  2067. ;--------------------------------------------------------------------------;
  2068.  
  2069. UP_ARROW:
  2070. ;----------------FW----------------------------------------------
  2071.                MOV    BX,COUNT
  2072.                CMP    BX,21
  2073.                JA     UP_ARROW1
  2074.                MOV    BX,LINE
  2075.                ADD    BX,-160                ;Move bar up one line.
  2076.                CMP    BX,PAGE_START-160      ;START OF LIST  \ROOT
  2077.                JA     UP_ARROW2
  2078.                JMP    END_BAR
  2079. UP_ARROW1:     MOV    BX,CUR_OFFSET
  2080.                ADD    BX,-160                ;Move bar up one line.
  2081.                CMP    BX,OFFSET BUFFER       ;START OF LIST
  2082.                JA     UP_ARROW2
  2083.                MOV    BX,LINE
  2084.                ADD    BX,-160                ;Move bar up one line.
  2085.                CMP    BX,PAGE_START-160      ;START OF LIST  \ROOT
  2086.                JA     UP_ARROW2
  2087.                JMP    END_BAR
  2088. UP_ARROW2:     MOV    BP,-160                ;Move bar up one line.
  2089.                JMP    SHORT BAR_MOVE
  2090.  
  2091. DN_ARROW:
  2092. ;----------------FW----------------------------------------------
  2093.                MOV    BX,COUNT
  2094.                CMP    BX,21
  2095.                JA     DN_ARROW1
  2096.                MOV    BX,LINE
  2097.                ADD    BX,160
  2098.                CMP    BX,PAGE_END            ;AT LAST LINE
  2099.                JAE    HOME_BAR
  2100.                JMP    DN_ARROW2
  2101.  
  2102. DN_ARROW1:     MOV    BX,CUR_OFFSET
  2103.                ADD    BX,21*FIELD_SIZE+160
  2104.                CMP    BX,END_OFFSET          ;AT LAST PAGE
  2105.                JBE    DN_ARROW2
  2106.                MOV    BX,LINE
  2107.                ADD    BX,160
  2108.                CMP    BX,PAGE_END            ;AT LAST LINE
  2109.                JB     DN_ARROW2
  2110.                JMP    HOME_BAR
  2111. ;----------------------------------------------------------------
  2112. DN_ARROW2:     MOV    BP,160                 ;Move bar down one line.
  2113. BAR_MOVE:      CALL   SCROLL_BAR
  2114.                RET
  2115.  
  2116. PG_UP:         MOV    BP,- FIELD_SIZE * 21   ;Move up 21 lines.
  2117.                CALL   SCROLL
  2118.                JMP    SHORT BOTTOM_BAR
  2119.  
  2120. PG_DN:         MOV    BP,FIELD_SIZE * 21     ;Move down 21 lines.
  2121. MOVE_PAGE:     CALL   SCROLL
  2122.                JMP    SHORT TOP_BAR          ;Move bar to top.
  2123.  
  2124. HOME_BAR:      MOV    CUR_OFFSET,OFFSET BUFFER   ;Move listing to beginning.
  2125. TOP_BAR:       MOV    SI,BAR_START               ;And move bar to top.
  2126.                CALL   MOVE_BAR
  2127.                RET
  2128.  
  2129. END_BAR:       MOV    BX,END_OFFSET          ;Move listing to last page.
  2130.                SUB    BX,21 * FIELD_SIZE
  2131.                CMP    BX,OFFSET BUFFER
  2132.                JBE    BOTTOM_BAR
  2133.                MOV    CUR_OFFSET,BX
  2134. BOTTOM_BAR:    MOV    SI,PAGE_END            ;And move bar to bottom.
  2135.                SUB    SI,160
  2136.                CALL   MOVE_BAR
  2137.                RET
  2138.  
  2139. ;------------------------------------------------------------------;
  2140. ; Read all the directory filenames and store as records in buffer. ;
  2141. ;------------------------------------------------------------------;
  2142. READ_DIR:      MOV    BP,OFFSET INPUT_DIR
  2143.                MOV    SI,OFFSET WORKING_DIR  ;Store working drive directory.
  2144.                CALL   GET_DIR
  2145.                CMP    RN_SWITCH,32           ;DID RN CALL
  2146.                JNE    MESSAGE
  2147.                CMP    INPUT_DIR+1,":"        ;Is there a drive request?
  2148.                JNZ    SET_DIR                ;directory change.
  2149.                INC    BP                     ; PAST
  2150.                INC    BP                     ;      DRIVE
  2151. SET_DIR:       CMP    BYTE PTR [BP],32       ;Is it a delimiter?
  2152.                JBE    MESSAGE                ;If yes, skip.
  2153.                MOV    DX,BP                  ;Retrieve start.
  2154.                CALL   CHANGE_DIR             ;Change directory.
  2155.                MOV    DX,OFFSET INVALID
  2156.                JNC    MESSAGE                ;If GOOD JUMP
  2157.                JMP    ERROR_EXIT             ;If error, exit.
  2158.  
  2159. MESSAGE:       CALL   CLS                    ;Clear screen.
  2160.                CALL   CURSOR_OFF             ;Cursor off.
  2161.                MOV    SI,OFFSET LOADING      ;Display sorting message.
  2162.                MOV    DX,0C19H
  2163.                CMP    SORT_FLAG,1            ;Unless not sorted.
  2164.                JNZ    DISP_MSG
  2165.                MOV    SI,OFFSET LOAD_ONLY    ;Then display loading message.
  2166.                MOV    DX,0C1FH
  2167. DISP_MSG:      CALL   DISPLAY_TEXT
  2168.                MOV    FILE_CNT,0000H         ;FILE COUNT = ZERO
  2169.                MOV    COUNT,0000H            ;FILE COUNT = ZERO
  2170.                MOV    DI,OFFSET BUFFER       ;Put space character
  2171.                MOV    CX,16000               ; in directory listing
  2172.                MOV    AX,2020H               ; buffer.
  2173.                REP    STOSW
  2174.  
  2175.                MOV    DX,OFFSET STAR_DOT_STAR
  2176.                MOV    CX,SEARCH_ATTRIB
  2177.                CALL   FIND_FIRST             ;Find first matching file.
  2178.                JNC    STORE_NAME             ;If empty directory, exit.
  2179.                MOV    DI,158                 ;Point to filename.
  2180.                MOV    SI,OFFSET NO_FILES     ;Point to MSG
  2181.                MOV    CX,12                  ;Store 12 bytes of filename.
  2182.                REP    MOVSB
  2183.  
  2184. STORE_NAME:    MOV    DI,OFFSET BUFFER + 1   ;Point to buffer.
  2185.                MOV    BP,SP                  ;Reserve space for stack.
  2186.                SUB    BP,500
  2187.                CALL   BUFFER_NAME            ;Convert to directory format.
  2188.  
  2189. FIND_NEXT:     MOV    AH,4FH                 ;Find next matching.
  2190.                INT    21H
  2191.                JC     STORE_COUNT            ;If carry, no more names.
  2192.                CALL   BUFFER_NAME
  2193.                CMP    DI,BP                  ;Are we encroaching the stack?
  2194.                JBE    FIND_NEXT              ;If no, find next.
  2195.                MOV    DX,OFFSET TOO_MANY     ;Else, exit with message.
  2196.  
  2197. ;-----------------------------------------------------------------------;
  2198. ; This is the exit routine. Restore the defaults the way we found them. ;
  2199. ;-----------------------------------------------------------------------;
  2200.  
  2201. ERROR_EXIT:    MOV    AH,9                   ;Display error message.
  2202.                INT    21H
  2203. ERROR_DISK:    MOV    TEMPUS_RETCODE,4        ;SET RETURN CODE
  2204.                MOV    AL,1                   ;Error code of one.
  2205.                JMP    SHORT TERMINATE
  2206.  
  2207. ESC_EXIT:
  2208.                CMP  DEFAULT_MENU,2         ;DEFAULT AT SHORT MENU
  2209.                JE   EXIT_PGM               ;YES
  2210.                CMP  M4,0                   ;SWITCH /M4 ENTERED
  2211.                JA   EXIT_PGM               ;YES
  2212.                MOV  DEFAULT_MENU,2         ;DEFAULT TO SHORT MENU
  2213.                CALL REFRESH_MENU           ;AND DISPLAY IT
  2214.                RET
  2215. EXIT_PGM:      MOV    TEMPUS_RETCODE,3        ;SET RETURN CODE
  2216. EXIT:          CALL   CLS                    ;Clear screen.
  2217.                XOR    DX,DX                  ;Set cursor top left.
  2218.                CALL   SET_CURSOR
  2219.                CALL   CURSOR_ON              ;Turn cursor back on.
  2220.                XOR    AL,AL                  ;Error code of zero.
  2221. TERMINATE:     PUSH   AX
  2222.                MOV    AL,CUR_VERIFY          ;Restore verify state.
  2223.                CALL   SET_VERIFY
  2224.                MOV    DL,CURRENT_DISK        ;Restore drive.
  2225.                CALL   CHANGE_DRIVE
  2226.                CALL   CURSOR_ON              ;Turn cursor back on.
  2227.                POP    AX
  2228.                MOV    AL,TEMPUS_RETCODE       ;SET RETURN CODE
  2229.                MOV    AH,4CH
  2230.                INT    21H
  2231.  
  2232. ;-----------------------------------;
  2233. ; Store buffer end address and page ;
  2234. ; end then sort the filenames.      ;
  2235. ;-----------------------------------;
  2236.  
  2237. STORE_COUNT:   DEC    DI
  2238.                MOV    END_OFFSET,DI          ;Store ending offset.
  2239.                MOV    BX,COUNT               ;Retrieve file count.
  2240.                CMP    BX,21                  ;Enough to fill one page?
  2241.                JAE    DO_SORT                ;If yes, use default setting.
  2242.                MOV    AX,160                 ;Calculate last record.
  2243.                MUL    BL
  2244.                ADD    AX,BAR_START           ;Add bar offset.
  2245.                MOV    PAGE_END,AX
  2246. DO_SORT:       CMP    SORT_FLAG,1            ;Should we sort or leave original?
  2247.                JZ     READY                  ;If it was "/O", don't sort.
  2248.                CALL   SORT
  2249.  
  2250. ;------------------------------------------------------------------------;
  2251. ; Now, we are ready to get target directory and display it and the menu. ;
  2252. ;------------------------------------------------------------------------;
  2253.  
  2254. READY:         MOV    DI,OFFSET PURGE_DIR B  ;Point to storage.
  2255.                CALL   GET_DRIVE              ;Get drive.
  2256.                MOV    PURGE_DISK,AL
  2257.                ADD    AL,"A"                 ;Convert to ASCII.
  2258.                STOSB
  2259.                MOV    AL,":"                 ;Add colon.
  2260.                STOSB
  2261.                MOV    SI,DI                  ;Get directory.
  2262.                CALL   GET_DIR
  2263.                MOV    SI,OFFSET PURGE_DIR B  ;Make a carbon copy of
  2264.                MOV    DI,OFFSET SOURCE B     ; directory.
  2265. CARBON_COPY:   MOVSB
  2266.                CMP    BYTE PTR [SI],0
  2267.                JNZ    CARBON_COPY
  2268.                MOV    AL,"\"                 ;Add "\" to end of path
  2269.                CMP    [DI-1],AL              ; if not root directory.
  2270.                JZ     STORE_END
  2271.                STOSB
  2272. STORE_END:     MOV    FILE_NAME,DI           ;Store end of path to tack
  2273.                CALL   UPDATE_FREE            ; on filename later on.
  2274.                MOV    DX,OFFSET WORKING_DIR  ;Restore the working directory.
  2275.                CALL   CHANGE_DIR
  2276.                MOV    DL,CURRENT_DISK        ;Restore to default drive
  2277.                CALL   CHANGE_DRIVE
  2278.                MOV    DX,OFFSET CURRENT_DIR  ; and default directory.
  2279.                CALL   CHANGE_DIR
  2280.                CALL   REFRESH_DIR            ;Display drive, directory, menu.
  2281.                RET
  2282.  
  2283. ;-----------------------------------------------------------------------;
  2284. ; This subroutine searches for a filename with a specific first letter. ;
  2285. ;-----------------------------------------------------------------------;
  2286.  
  2287. SEARCH:        CMP    BL,"a"                 ;Capitalize if lower case.
  2288.                JB     SEARCH_IT
  2289.                CMP    BL,"z"
  2290.                JA     SEARCH_IT
  2291.                AND    BL,5FH
  2292. SEARCH_IT:     CALL   GET_NAME               ;Get current position.
  2293.                XOR    DX,DX                  ;Zero out file counter.
  2294.                MOV    DI,SI                  ;Store current position in DI.
  2295.                MOV    SI,OFFSET BUFFER + 1   ;Point to top of listing.
  2296.                CMP    BYTE PTR [DI],BL       ;Are we currently at a match?
  2297.                JNZ    NEXT_SEARCH            ;If no, start from top.
  2298. FIND_START:    INC    DX                     ;Increment count.
  2299.                ADD    SI,FIELD_SIZE          ;Increment record.
  2300.                CMP    SI,DI                  ;New record?
  2301.                JBE    FIND_START             ;If no, find it.
  2302.  
  2303. NEXT_SEARCH:   CMP    BYTE PTR [SI],BL       ;Got a match?
  2304.                JZ     FOUND_IT               ;If yes, process.
  2305. INC_SEARCH:    ADD    SI,FIELD_SIZE          ;Else, point to next record.
  2306.                INC    DX
  2307.                CMP    BYTE PTR [SI],32       ;End of listing?
  2308.                JNZ    NEXT_SEARCH            ;If no, keep searching.
  2309.                CALL   BEEP                   ;No matches, so beep.
  2310.                RET
  2311.  
  2312. FOUND_IT:      MOV    CX,COUNT               ;Retrieve file count.
  2313.                SUB    CX,DX                  ;Subtract search count.
  2314.                MOV    SEARCH_COUNT,CX        ;And store.
  2315.                MOV    CL,ATTR_TREE           ;Turn off bar for now.
  2316.                MOV    BAR_ATTRIBUTE,CL
  2317.                CALL   END_BAR                ;First move to end.
  2318.                JMP    SHORT FIND_IT
  2319. NEXT_FIND:     CALL   UP_ARROW2              ;Move up to matching filename.
  2320. FIND_IT:       DEC    SEARCH_COUNT
  2321.                JNZ    NEXT_FIND
  2322.                MOV    CL,INVERSE             ;Turn bar back on and display.
  2323.                MOV    BAR_ATTRIBUTE,CL
  2324.                XOR    BP,BP
  2325.                CALL   SCROLL_BAR
  2326.                RET
  2327.  
  2328. ;--------------------------------------------------------------------------;
  2329. ; This subroutine gets the highlighted file and converts it to DOS format. ;
  2330. ;--------------------------------------------------------------------------;
  2331.  
  2332. GET_NAME:      MOV    SI,CUR_OFFSET          ;Get top of page.
  2333.                INC    SI                     ;Bump past mark field.
  2334.                MOV    AX,LINE                ;Get location of bar.
  2335.                SUB    AX,BAR_START           ;Adjust.
  2336.                MOV    CL,160                 ;Convert to byte pointer.
  2337.                DIV    CL
  2338.                MOV    CL,FIELD_SIZE
  2339.                MUL    CL
  2340.                ADD    SI,AX                  ;Add to current offset.
  2341.                MOV    CUR_FILE,SI            ;And save pointer.
  2342.                PUSH   SI
  2343.                MOV    DI,FILE_NAME           ;Store the first eight characters.
  2344.                MOV    CX,8
  2345.                CALL   STORE_BYTES
  2346.                INC    SI
  2347.                CMP    BYTE PTR DS:[SI],32    ;End of name?
  2348.                JZ     END_NAME               ;If yes, done here.
  2349.                MOV    AL,"."                 ;Else, add dot.
  2350.                STOSB
  2351.                MOV    CX,3                   ;Three possible characters
  2352.                CALL   STORE_BYTES            ; as extension.
  2353. END_NAME:      MOV    BYTE PTR [DI],0        ;Convert to ASCIIZ.
  2354.                POP    SI
  2355.                CMP    BYTE PTR [SI+13],"<"   ;Is it a directory?
  2356.                STC
  2357.                JZ     NAME_ERROR             ;If yes, indicate so.
  2358.                CLC
  2359. NAME_ERROR:    RET
  2360.  
  2361. STORE_BYTES:   LODSB                         ;Get a character.
  2362.                CMP    AL,32                  ;If it's space, skip.
  2363.                JZ     SKIP_STORE
  2364.                STOSB
  2365. SKIP_STORE:    LOOP   STORE_BYTES
  2366.                RET
  2367.  
  2368. ;-----------------------------------------------------------;
  2369. ; This subroutine moves and turns the cursor on and removes ;
  2370. ; the last user entry in preparation for new input.         ;
  2371. ;-----------------------------------------------------------;
  2372.  
  2373. CLEAR_OLD:     CALL   SET_CURSOR             ;Move cursor.
  2374.                CALL   CURSOR_ON              ;Turn it on.
  2375.                MOV    DI,OFFSET ENTRY B      ;Write nulls over old entry.
  2376.                XOR    AX,AX
  2377.                MOV    CX,18
  2378.                REP    STOSW
  2379.                MOV    DI,OFFSET ENTRY B      ;Initiate pointer for entry.
  2380.                RET
  2381.  
  2382. ;-----------------------------;
  2383. ; This subroutine backspaces. ;
  2384. ;-----------------------------;
  2385.  
  2386. MOVE_BS:       CMP    DI,OFFSET ENTRY B      ;At beginning of field?
  2387.                JZ     MOVE_BS_END            ;If yes, skip.
  2388.                DEC    DI                     ;Else, decrement pointer.
  2389.                MOV    BYTE PTR [DI],0
  2390.                MOV    SI,OFFSET BS           ;Erase last character.
  2391.                CALL   GET_TEXT
  2392. MOVE_BS_END:   RET
  2393.  
  2394. ;------------------------------------------------------------------;
  2395. ; This subroutine removes the filename from the directory listing. ;
  2396. ;------------------------------------------------------------------;
  2397.  
  2398. REMOVE_FILE:   MOV    DI,CUR_FILE            ;Point to filename.
  2399.                DEC    DI                     ;Include mark field.
  2400.                MOV    SI,DI                  ;Move all the records
  2401.                ADD    SI,FIELD_SIZE          ; that follow up one.
  2402. NEXT_RECORD:   MOV    CX,FIELD_SIZE / 2
  2403.                REP    MOVSW
  2404.                CMP    DI,END_OFFSET
  2405.                JB     NEXT_RECORD
  2406.                SUB    DI,FIELD_SIZE
  2407.                MOV    END_OFFSET,DI          ;Store new end.
  2408.                XOR    BP,BP
  2409.                CALL   SCROLL                 ;Update the screen.
  2410.                DEC    COUNT
  2411.                DEC    FILE_CNT               ;Decrement file count.
  2412.                JNZ    MORE_FILES             ;If empty, exit.
  2413.                JMP    EXIT
  2414. MORE_FILES:    CMP    COUNT,21               ;Full page?
  2415.                JAE    REMOVE_END             ;If yes, skip.
  2416.                SUB    PAGE_END,160           ;Else, adjust page end.
  2417.                MOV    SI,PAGE_END
  2418.                SUB    SI,160
  2419.                CMP    SI,LINE                ;Is bar below directory listing?
  2420.                JA     REMOVE_END             ;If no, skip.
  2421.                CALL   MOVE_BAR               ;Else, move bar up one line.
  2422. REMOVE_END:    RET
  2423.  
  2424. ;----------------------------------------------;
  2425. ; This subroutine displays the count of files. ;
  2426. ;----------------------------------------------;
  2427.  
  2428. FILE_COUNT:    MOV    DI,OFFSET FILES        ;Blank out previous count.
  2429.                MOV    AX,2020H
  2430.                STOSW
  2431.                MOV    AX,FILE_CNT
  2432.                XOR    DX,DX
  2433.                CALL   TRANSLATE
  2434.  
  2435. DISPLAY_BYTES: MOV    DX,1806H               ;Row 24; column 6.
  2436.                MOV    SI,OFFSET FILES        ;Display file count.
  2437.                CALL   DISPLAY_TEXT
  2438.                RET
  2439.  
  2440. ;---------------------------------------------------;
  2441. ; This subroutine converts a hex number to decimal. ;
  2442. ;---------------------------------------------------;
  2443.  
  2444. TRANSLATE:     XCHG   AX,DX
  2445.                MOV    BX,10                  ;Convert to decimal.
  2446.                STD                           ;Reverse direction.
  2447. NEXT_COUNT:    MOV    CX,DX
  2448.                XOR    DX,DX
  2449.                DIV    BX
  2450.                XCHG   AX,CX
  2451.                DIV    BX
  2452.                XCHG   AX,DX
  2453.                ADD    AL,"0"                 ;Convert to ASCII.
  2454.                STOSB                         ;Store the remainder.
  2455.                MOV    AX,CX
  2456.                OR     CX,DX
  2457.                JNZ    NEXT_COUNT
  2458.                CLD                           ;Back to forward direction.
  2459.                RET
  2460.  
  2461. ;----------------------------------------------------------------------------;
  2462. ; This subroutine displays the current directory, menu, and number of files. ;
  2463. ;----------------------------------------------------------------------------;
  2464.  
  2465. REFRESH_DIR:   CALL   CLS                    ;Clear the screen.
  2466. REFRESH_MENU:
  2467.                MOV    SI,OFFSET MENU         ;Point to menu position.
  2468.                CMP    DEFAULT_MENU,1
  2469.                JE     LONG_MENU
  2470.                MOV    SI,OFFSET MENU2        ;Point to menu2 position.
  2471. LONG_MENU:
  2472.                MOV    DI,(1*160)+98          ;And to screen position.
  2473.                MOV    BH,MENU_LGTH           ;Display 20 lines of menu.
  2474. NEXT_REFRESH:  MOV    CX,MENU_WIDTH          ;22 characters per line.
  2475. NEXT_MENU:     LODSB
  2476.                MOV    BL,AL
  2477.                CALL   WRITE_SCREEN
  2478. ;----------------------FW--------------------------------------
  2479.                MOV    BL,ATTR_MENU          ;<<<<<<
  2480.                DEC    DI
  2481.                CALL   WRITE_SCREEN
  2482.                DEC    DI
  2483. ;----------------------FW--------------------------------------
  2484.                LOOP   NEXT_MENU
  2485.                ADD    DI,160-(MENU_WIDTH*2)  ;Next line.
  2486.                DEC    BH
  2487.                JNZ    NEXT_REFRESH
  2488.  
  2489.                MOV    DX,2
  2490.                MOV    SI,OFFSET DIRECTORY    ;Display "Directory ".
  2491.                CALL   DISPLAY_TEXT
  2492.                MOV    SI,OFFSET PURGE_DIR B  ;Display working directory.
  2493.                CALL   GET_TEXT
  2494.                CMP    OUTPUT_DIR,00          ;WAS THERE AN OUTPUT ENTERE
  2495.                JE     SKIP_OUTPUT            ;IF NOT SKIP
  2496.                MOV    SI,OFFSET COPY_MOVE    ;Display "Copy or Move to"
  2497.                CALL   GET_TEXT
  2498.                MOV    SI,OFFSET OUTPUT_DIR   ;Display output drive & dir
  2499.                CALL   GET_TEXT
  2500. SKIP_OUTPUT:   CALL   FILE_COUNT             ;Display file count.
  2501. ;--------------FW-----------------------------------------------
  2502.                MOV    AX,LINE
  2503.                PUSH   AX
  2504.                MOV    LINE,0
  2505.                CALL   UPDATE_SCREEN
  2506.                POP    AX
  2507.                MOV    LINE,AX
  2508. ;---------------------------------------------------------------
  2509.                MOV    BL,INVERSE             ;Put up cursor bar.
  2510.                CALL   BAR
  2511.                RET
  2512.  
  2513. ;-------------------------------------;
  2514. ; This subroutine scrolls the screen. ;
  2515. ;-------------------------------------;
  2516.  
  2517. SCROLL:        MOV    SI,CUR_OFFSET          ;Get current offset.
  2518.                ADD    SI,BP                  ;Add requested direction.
  2519. CK_LOWER:      CMP    SI,OFFSET BUFFER       ;If above start check upper limit.
  2520.                JAE    UPPER_LIMIT
  2521. LOWER_LIMIT:   MOV    CUR_OFFSET,OFFSET BUFFER    ;Else, make it start.
  2522.                JMP    SHORT SCROLL_RETURN         ;And update screen.
  2523.  
  2524. UPPER_LIMIT:   MOV    BX,END_OFFSET                      ;See if beyond end of
  2525.                CMP    BX,OFFSET BUFFER + 21 * FIELD_SIZE ; directory listing.
  2526.                JA     CK_UPPER
  2527.                MOV    CUR_OFFSET,OFFSET BUFFER
  2528.                JMP    SHORT SCROLL_RETURN
  2529.  
  2530. CK_UPPER:      SUB    BX,21 * FIELD_SIZE
  2531.                CMP    SI,BX
  2532.                JBE    END_SCROLL
  2533.                MOV    SI,BX
  2534.  
  2535. END_SCROLL:    MOV    CUR_OFFSET,SI          ;Update current offset.
  2536. SCROLL_RETURN:
  2537.                RET
  2538.  
  2539. ;--------------------------------------------------;
  2540. ; This subroutine scrolls the bar if between start ;
  2541. ; and end of page. Otherwise the page is scrolled. ;
  2542. ;--------------------------------------------------;
  2543.  
  2544. SCROLL_BAR:    MOV    SI,LINE                ;Get current line.
  2545.                ADD    SI,BP                  ;Add requested line.
  2546.                MOV    BP,- FIELD_SIZE        ;Assume below beginning.
  2547.                CMP    SI,BAR_START           ;Is it?
  2548.                JB     SCROLL_PAGE            ;If yes, scroll page instead.
  2549.                MOV    BP,FIELD_SIZE          ;Do the same for end of page.
  2550.                CMP    SI,PAGE_END
  2551.                JAE    SCROLL_PAGE
  2552.                CALL   MOVE_BAR
  2553.                RET
  2554.  
  2555. SCROLL_PAGE:   CALL   SCROLL
  2556.                RET
  2557.  
  2558. ;----------------------------------------------------;
  2559. ; This subroutine does the actual moving of the bar. ;
  2560. ;----------------------------------------------------;
  2561.  
  2562. MOVE_BAR:
  2563.                MOV    BL,ATTR_TREE           ;Remove old bar.
  2564.                CALL   BAR
  2565.                MOV    LINE,SI                ;And move bar to new line.
  2566.                MOV    BL,BAR_ATTRIBUTE
  2567.                CALL   BAR
  2568.                RET
  2569.  
  2570. BAR:           MOV    DI,LINE                ;Retrieve line.
  2571.                MOV    CX,BAR_LENGTH          ;Bar length 39.
  2572. NEXT_BAR:      CALL   WRITE_SCREEN           ;Write the attribute.
  2573.                LOOP   NEXT_BAR
  2574.                RET
  2575.  
  2576. ;-------------------------------------------------;
  2577. ; This subroutine displays the directory listing. ;
  2578. ;-------------------------------------------------;
  2579.  
  2580. UPDATE_SCREEN: XOR    BP,BP
  2581.                MOV    SI,CUR_OFFSET          ;Retrieve starting offset.
  2582.                MOV    DI,2*160               ;Point to row two of screen.
  2583.                MOV    BH,21                  ;21 lines to write.
  2584. NEXT_WRITE:    MOV    CX,FIELD_SIZE          ;44 characters per line.
  2585.                MOV    BL,ATTR_TREE           ;ELSE USE TREE ATTR
  2586.                MOV    ATTR_SAVE,BL           ;ELSE USE TREE ATTR
  2587. NEXT_CHAR:
  2588. ;----------------------FW--------------------------------------
  2589.                MOV    AX,LINE
  2590.                ADD    AX,-1
  2591.                CMP    AX,DI                  ;FIND HIGHLIGH
  2592.                JNE    MOVE_ATTR
  2593.                MOV    BL,BAR_ATTRIBUTE
  2594.                MOV    ATTR_SAVE,BL           ;ELSE USE BAR ATTR
  2595. MOVE_ATTR:
  2596. ;--------------------------------------------------------------
  2597.                LODSB                         ;Get a byte.
  2598.                MOV    BL,AL                  ;Save it in BL.
  2599.                CALL   WRITE_SCREEN           ;Write them.
  2600. ;----------------------FW--------------------------------------
  2601.                MOV    BL,ATTR_SAVE           ;ELSE USE TREE ATTR
  2602.                DEC    DI
  2603.                CALL   WRITE_SCREEN
  2604.                DEC    DI
  2605. ;--------------------------------------------------------------
  2606.                LOOP   NEXT_CHAR
  2607. NOATTR:        ADD    DI,160 - FIELD_SIZE * 2   ;Bump pointer to next line.
  2608.                DEC    BH                        ;Do all 21 lines.
  2609.                JNZ    NEXT_WRITE
  2610.                RET
  2611.  
  2612. ;------------------------------------------------------------;
  2613. ; This subroutine displays the directory by writing directly ;
  2614. ; to the screen buffer. To avoid screen noise (snow) on the  ;
  2615. ; color card, the horizontal retrace has to be monitored.    ;
  2616. ;------------------------------------------------------------;
  2617.  
  2618. WRITE_SCREEN:  MOV    DX,STATUS_REG          ;Retrieve status register.
  2619.                MOV    AX,VIDEO_SEG           ;Point to screen segment.
  2620.                MOV    ES,AX
  2621.  
  2622. HORZ_RET:      IN     AL,DX                  ;Get status.
  2623.                TEST   AL,1                   ;Is it low?
  2624.                JNZ    HORZ_RET               ;If not, wait until it is.
  2625.                CLI                           ;No more interrupts.
  2626.  
  2627. HWAIT:         IN     AL,DX                  ;Get status.
  2628.                TEST   AL,1                   ;Is it high?
  2629.                JZ     HWAIT                  ;If no, wait until it is.
  2630.                MOV    AL,BL                  ;Retrieve character; now it's OK
  2631.                STOSB                         ; to write to screen buffer.
  2632.                STI                           ;Interrupts back on.
  2633.                INC    DI                     ;Bump pointer past attribute.
  2634.                PUSH   CS
  2635.                POP    ES
  2636.                RET                           ;Return
  2637.  
  2638. ;-----------------------------------------------------------------------;
  2639. ; These two subroutines clear either the messages or the entire screen. ;
  2640. ;-----------------------------------------------------------------------;
  2641.  
  2642. CLS_TEXT:      XOR    CX,CX
  2643.                MOV    DX,184FH               ;Entire screen.
  2644.                JMP    CLEAR_WINDOW
  2645.  
  2646. CLS:           XOR    CX,CX
  2647.                MOV    DX,184FH               ;Entire screen.
  2648.                CALL   CLEAR_WINDOW
  2649.  
  2650. CLEAR_MSG:     MOV    CX,152CH               ;Row 24; column 43.
  2651.                MOV    DX,184FH               ;Row 25; column 79.
  2652.                PUSH   BP
  2653.                PUSH   BX
  2654.                MOV    BH,ATTR_MSGS          ;Clear with original attribute.
  2655.                JMP    SHORT CLEAR_WINDOW2
  2656.  
  2657. CLEAR_WINDOW:  PUSH   BP
  2658.                PUSH   BX
  2659.                MOV    BH,ATTR_TEXT          ;Clear with original attribute.
  2660. CLEAR_WINDOW2: MOV    AX,600H
  2661.                INT    10H
  2662.                POP    BX
  2663.                POP    BP
  2664.                RET
  2665.  
  2666. ;-----------------------------------------;
  2667. ; These subroutines display the messages. ;
  2668. ;-----------------------------------------;
  2669.  
  2670. DISPLAY_TEXT:  CALL   SET_CURSOR             ;Move cursor.
  2671. GET_TEXT:      LODSB
  2672.                CMP    AL,0                   ;Zero marks end of string.
  2673.                JZ     END_TEXT
  2674. ;--------------------FW----------------------------------------
  2675.                MOV    BL,ATTR_MSGS
  2676. ;--------------------------------------------------------------
  2677.                CALL   WRITE_TEXT
  2678.                JMP    SHORT GET_TEXT
  2679. END_TEXT:      RET
  2680.  
  2681. WRITE_TEXT:    PUSH   SI                     ;BIOS does not save SI.
  2682.                MOV    AH,0EH                 ;Write teletype.
  2683.                INT    10H
  2684.                POP    SI
  2685.                RET
  2686.  
  2687. ;--------------------------------------------------------------;
  2688. ; These two subroutines change the default drive or directory. ;
  2689. ;--------------------------------------------------------------;       *
  2690.  
  2691. GET_DRIVE:     MOV    AH,19H
  2692.                INT    21H
  2693.                RET
  2694.  
  2695. CHANGE_DRIVE:  MOV    AH,0EH
  2696.                INT    21H
  2697.                RET
  2698.  
  2699. ;---------------------------------------------;
  2700. ; These two subroutines open or close a file. ;
  2701. ;---------------------------------------------;
  2702.  
  2703. OPEN_FILE:     MOV    AH,3DH
  2704.                INT    21H
  2705.                RET
  2706.  
  2707. CLOSE_FILE:    MOV    AH,3EH
  2708.                INT    21H
  2709.                RET
  2710.  
  2711. ;------------------------------------------------;
  2712. ; This subroutine finds the first matching file. ;
  2713. ;------------------------------------------------;
  2714.  
  2715. FIND_FIRST:    MOV    AH,4EH
  2716.                INT    21H
  2717.                RET
  2718.  
  2719. ;--------------------------------------------------------------;
  2720. ; These two subroutines retrieve or change a file's attribute. ;
  2721. ;--------------------------------------------------------------;
  2722.  
  2723. CHMOD:         MOV    AX,4301H
  2724.                INT    21H
  2725.                RET
  2726.  
  2727. GETMOD:        MOV    AX,4300H
  2728.                INT    21H
  2729.                RET
  2730.  
  2731. ;---------------------------------------------------------;
  2732. ; This subroutine gets the free disk space of the target. ;
  2733. ;---------------------------------------------------------;
  2734.  
  2735. GET_DISK:      MOV    SI,DX                  ;Retrieve pointer to target file.
  2736.                MOV    DL,-1                  ;Assume default drive.
  2737.                CMP    BYTE PTR [SI+1],":"    ;Is there a drive request?
  2738.                JNZ    GET_FREE               ;If no, get default drive.
  2739.                MOV    DL,[SI]                ;Else, retrieve drive request.
  2740.                AND    DL,5FH                 ;Capitalize.
  2741.                SUB    DL,"A"                 ;Convert to DOS format.
  2742. GET_FREE:      CALL   DISK_FREE              ;Get free bytes.
  2743.                RET
  2744.  
  2745. ;--------------------------------------------------------------;
  2746. ; This subroutine gets the free disk space of the source drive ;
  2747. ;--------------------------------------------------------------;
  2748.  
  2749. UPDATE_FREE:   MOV    DL,PURGE_DIR B         ;Get source drive.
  2750.                SUB    DL,"A"                 ;Convert to DOS format.
  2751.                CALL   DISK_FREE              ;Get disk free space.
  2752.                MOV    DI,OFFSET FILES + 20   ;Point to storage.
  2753.                CALL   TRANSLATE              ;Convert hex to decimal and store.
  2754.                RET
  2755.  
  2756. ;----------------------------------------------;
  2757. ; This subroutine retrieves available clusters ;
  2758. ; and converts it to hexidecimal bytes free.   ;
  2759. ;----------------------------------------------;
  2760.  
  2761. DISK_FREE:     INC    DL                     ;Adjust drive.
  2762.                MOV    AH,36H                 ;Disk free space.
  2763.                INT    21H
  2764.                XOR    DX,DX
  2765.                MUL    BX                     ;Sectors per cluster times clusters
  2766.                MUL    CX                     ;Result times bytes per cluster.
  2767.                RET
  2768.  
  2769. ;------------------------------------------;
  2770. ; This subroutine converts hex to decimal. ;
  2771. ;------------------------------------------;
  2772.  
  2773. GET_COUNT:     MOV    BX,10                  ;Convert to decimal.
  2774.                XOR    CX,CX                  ;Zero in counter.
  2775. GET_NUMBER:    XOR    DX,DX                  ;Zero in high half.
  2776.                DIV    BX
  2777.                ADD    DL,"0"                 ;Convert to ASCII.
  2778.                PUSH   DX                     ;Save results.
  2779.                INC    CX                     ;Also increment count.
  2780.                CMP    AX,0                   ;Are we done?
  2781.                JNZ    GET_NUMBER
  2782.  
  2783. NEXT_NUMBER:   POP    AX                     ;Retrieve numbers.
  2784.                CALL   WRITE_TEXT             ;And write them.
  2785.                LOOP   NEXT_NUMBER
  2786.                RET
  2787.  
  2788. ;---------------------------------------------------------;
  2789. ; These five subroutines move the cursor, get the current ;
  2790. ; directory, beep the speaker, check or get a keystroke.  ;
  2791. ;---------------------------------------------------------;
  2792.  
  2793. SET_CURSOR:    PUSH   SI
  2794.                XOR    BH,BH                  ;Page zero.
  2795.                MOV    AH,2                   ;Set cursor.
  2796.                INT    10H
  2797.                POP    SI
  2798.                RET
  2799.  
  2800. GET_DIR:       MOV    BYTE PTR [SI],"\"      ;DOS doesn't preface directory
  2801.                INC    SI                     ; with slash so we must.
  2802.                XOR    DL,DL
  2803.                MOV    AH,47H                 ;Retrieve default directory.
  2804.                INT    21H
  2805.                RET
  2806.  
  2807. BEEP:          MOV    DL,7                   ;Beep via DOS.
  2808.                MOV    AH,2
  2809.                INT    21H
  2810.                RET
  2811.  
  2812. READ_KEY:      MOV    AH,0                   ;Retrieve keystroke via BIOS.
  2813.                INT    16H
  2814.                RET
  2815.  
  2816. CK_KEY:        MOV    AH,1                   ;Check for keystroke via BIOS.
  2817.                INT    16H
  2818.                RET
  2819.  
  2820. ;-------------------------------------------------------------;
  2821. ; This subroutine waits until a keystroke is pressed and then ;
  2822. ; clears the message.  Keystroke remains in keyboard buffer.  ;
  2823. ;-------------------------------------------------------------;
  2824.  
  2825. DELAY:         CALL   CK_KEY
  2826.                JZ     DELAY
  2827.                CALL   CLEAR_MSG
  2828.                RET
  2829.  
  2830. ;-----------------------------------------------;
  2831. ; These subroutines turn the cursor off and on. ;
  2832. ;-----------------------------------------------;
  2833.  
  2834. CURSOR_OFF:    MOV    CX,2000H
  2835.                JMP    SHORT SET_TYPE
  2836.  
  2837. CURSOR_ON:     MOV    CX,CURSOR_TYPE
  2838.  
  2839. SET_TYPE:      MOV    AH,1
  2840.                INT    10H
  2841.                RET
  2842.  
  2843. ;------------------------------------------------;
  2844. ; This subroutine changes the default directory. ;
  2845. ;------------------------------------------------;
  2846.  
  2847. CHANGE_DIR:    MOV    AH,3BH
  2848.                INT    21H
  2849.                RET
  2850.  
  2851. ;------------------------------------------------;
  2852. ; This subroutine changes the copy verify state. ;
  2853. ;------------------------------------------------;
  2854.  
  2855. SET_VERIFY:    MOV    AH,2EH
  2856.                INT    21H
  2857.                RET
  2858.  
  2859. ;------------------------------------------;
  2860. ; This subroutine MOVES TEST FROM SI TO DI ;
  2861. ;------------------------------------------;
  2862.  
  2863. MOVE_TEXT:     LODSB
  2864.                CMP    AL,0                   ;Zero marks end of string.
  2865.                JZ     MOVE_TEXT_END
  2866.                STOSB
  2867.                JMP    MOVE_TEXT
  2868. MOVE_TEXT_END: RET
  2869.  
  2870. ;--------------------------------------------------;
  2871. ; This long subroutine stores the filename in DIR  ;
  2872. ; format. That is, filename, bytes, date and time. ;
  2873. ;--------------------------------------------------;
  2874.  
  2875. BUFFER_NAME:   MOV    SI,158                 ;Point to filename.
  2876.                MOV    CX,12                  ;Store 12 bytes of filename.
  2877.                CMP    BYTE PTR [SI],"."      ;Is it a dot directory?
  2878.                JNZ    INC_COUNT              ;If no, it's a file.
  2879.                JMP    DONT_STORE             ;If no, single dot so skip.
  2880.                CMP    BYTE PTR [SI+1],"."    ;Is it a double dot directory?
  2881.                JNZ    DONT_STORE             ;If no, single dot so skip.
  2882.                INC    COUNT                  ;Else, increment total count.
  2883.                LODSB                         ;Store dots and go to file size.
  2884.                STOSB
  2885.                STOSB
  2886.                ADD    DI,10
  2887.                JMP    SHORT FILE_SIZE
  2888. DONT_STORE:    RET
  2889.  
  2890. INC_COUNT:     INC    COUNT                  ;Increment total count.
  2891. NEXT_STORE:    LODSB                         ;Get a byte.
  2892.                CMP    AL,0                   ;End of filename?
  2893.                JZ     END_STORE              ;If yes, finish with blanks.
  2894.                CMP    AL,"."                 ;Is it the period?
  2895.                JNZ    STORE_BYTE             ;If no, store.
  2896.                SUB    CX,3                   ;Else store 3 spaces.
  2897.                MOV    AL,32
  2898.                REP    STOSB
  2899.                ADD    CX,3
  2900.                JMP    SHORT NEXT_STORE       ;Get next byte.
  2901.  
  2902. STORE_BYTE:    STOSB                         ;Store byte.
  2903.                LOOP   NEXT_STORE             ;Get next byte.
  2904. END_STORE:     MOV    AL,32                  ;Pad balance with spaces.
  2905.                REP    STOSB
  2906.  
  2907. FILE_SIZE:     PUSH   DI                     ;Save pointer.
  2908.                TEST   BYTE PTR DS:[149],10H  ;Is it a directory?
  2909.                JZ     STORE_SIZE             ;If no, store size.
  2910.                MOV    SI,OFFSET DIRECTORIES  ;Else, store "<DIR>".
  2911.                INC    DI
  2912.                MOV    CX,5
  2913.                REP    MOVSB
  2914.                JMP    SHORT END_DATE
  2915.  
  2916. STORE_SIZE:    INC    FILE_CNT               ;Increment file count.
  2917.                ADD    DI,8                   ;Move to end of bytes field.
  2918.                MOV    DX,DS:[156]            ;Retrieve high and low words
  2919.                MOV    AX,DS:[154]            ; of bytes.
  2920.                CALL   TRANSLATE              ;Convert to decimal.
  2921.  
  2922. END_DATE:      POP    DI                     ;Retrieve pointer.
  2923.                ADD    DI,11                  ;Move to date field.
  2924. DATE:          MOV    DX,DS:[152]            ;Retrieve date.
  2925.                MOV    AX,DX
  2926.                MOV    CL,5                   ;Shift to lowest bits.
  2927.                ROR    AX,CL
  2928.                AND    AX,0FH                 ;Mask off all but month.
  2929.                MOV    CL,0FFH                ;Flag as no leading zeros.
  2930.                MOV    CH,"-"                 ;Delimiting character.
  2931.                CALL   STORE_WORD             ;Store it.
  2932.  
  2933.                MOV    AX,DX                  ;Retrieve date.
  2934.                AND    AX,1FH                 ;Mask off all but day.
  2935.                MOV    CL,0                   ;Flag include leading zeros.
  2936.                MOV    CH,"-"
  2937.                CALL   STORE_WORD             ;Store it.
  2938.  
  2939.                MOV    AX,DX                  ;Retrieve date for last time.
  2940.                MOV    CL,9
  2941.                ROR    AX,CL
  2942.                AND    AX,7FH                 ;Mask off all but year.
  2943.                ADD    AX,80                  ;Adjust to ASCII.
  2944.                CMP    AX,100                 ;Past year 2000?
  2945.                JB     DISPLAY_DATE           ;If no, display. Else, adjust for
  2946.                SUB    AX,100                 ; next century. (Planning ahead!)
  2947. DISPLAY_DATE:  MOV    CL,0                   ;Display leading zeros.
  2948.                MOV    CH,32
  2949.                CALL   STORE_WORD             ;Store it.
  2950.  
  2951. TIME:          INC    DI                     ;Move to time field.
  2952.                MOV    DX,DS:[150]            ;Retrieve time.
  2953.                MOV    AX,DX
  2954.                MOV    CL,11                  ;Shift to hours bits.
  2955.                ROR    AX,CL
  2956.                AND    AX,1FH                 ;Mask off all but hours.
  2957.                PUSH   AX
  2958.                CMP    AX,12                  ;Past noon?
  2959.                JBE    MERIDIAN
  2960.                SUB    AX,12                  ;If yes, adjust.
  2961. MERIDIAN:      CMP    AX,0                   ;Midnight?
  2962.                JNZ    NOT_MIDNIGHT
  2963.                MOV    AX,12                  ;If yes, adjust.
  2964. NOT_MIDNIGHT:  MOV    CL,0FFH                ;Suppress leading zeros.
  2965.                MOV    CH,":"
  2966.                CALL   STORE_WORD             ;Store it.
  2967.  
  2968.                MOV    AX,DX                  ;Retrieve time.
  2969.                MOV    CL,5                   ;Shift to minutes bits.
  2970.                ROR    AX,CL
  2971.                AND    AX,3FH                 ;Mask off all but minutes.
  2972.                MOV    CL,0
  2973.                POP    DX                     ;Retrieve hours.
  2974.                MOV    CH,"p"                 ;Assume PM.
  2975.                CMP    DX,12                  ;Is it PM?
  2976.                JAE    PM
  2977.                MOV    CH,"a"                 ;If no, AM.
  2978.  
  2979. PM:            CALL   STORE_WORD             ;Store it.
  2980.                MOV    AH,BYTE PTR DS:[149]   ;Get attribute byte.
  2981.                MOV    AL,"H"                 ;Assume it's hidden.
  2982.                TEST   AH,2                   ;Is it?
  2983.                JNZ    HIDDEN                 ;If yes, store "H".
  2984.                MOV    AL,32                  ;Else, store a space.
  2985. HIDDEN:        STOSB
  2986.                MOV    AL,"S"                 ;Assume it's system.
  2987.                TEST   AH,4                   ;Is it?
  2988.                JNZ    SYSTEM                 ;If yes, store "S".
  2989.                MOV    AL,32                  ;Else, store a space.
  2990. SYSTEM:        STOSB
  2991.                MOV    AL,"R"                 ;Assume it's read-only.
  2992.                TEST   AH,1                   ;Is it?
  2993.                JNZ    READ_ONLY              ;If yes, store "R".
  2994.                MOV    AL,32                  ;Else, store a space.
  2995. READ_ONLY:     STOSB
  2996.                MOV    AL,"A"                 ;Assume it's archive.
  2997.                TEST   AH,20H                 ;is it?
  2998.                JNZ    ARCHIVE                ;If yes, store "A".
  2999.                MOV    AL,32                  ;Else store a space.
  3000. ARCHIVE:       STOSB
  3001.                INC    DI                     ;Bump pointer past mark field.
  3002.                RET
  3003.  
  3004. ;-------------------------------;
  3005.  
  3006. STORE_WORD:    MOV    BL,10
  3007.                DIV    BL                     ;Divide by ten.
  3008.                ADD    AX,"00"                ;Convert to ASCII.
  3009.                CMP    CL,0                   ;Are we to display leading zero?
  3010.                JZ     STORE_IT               ;If yes, store as is.
  3011.                CMP    AL,"0"                 ;Is it a leading zero?
  3012.                JNZ    STORE_IT               ;If no, store it.
  3013.                MOV    AL,32                  ;Else, store a space.
  3014. STORE_IT:      STOSW
  3015.                MOV    AL,CH                  ;Store delimiter character also.
  3016.                STOSB
  3017.                RET
  3018.  
  3019. ;-------------------------------------------;
  3020. ; This is the new Critical Error interrupt. ;
  3021. ;-------------------------------------------;
  3022.  
  3023. DISK_ERROR:    STI                           ;Interrupts back on.
  3024.                PUSHF                         ;Save all registers.
  3025.                PUSH   AX
  3026.                PUSH   BX
  3027.                PUSH   CX
  3028.                PUSH   DX
  3029.                PUSH   SI
  3030.                PUSH   DI
  3031.                PUSH   BP
  3032.                PUSH   DS
  3033.                PUSH   ES
  3034.  
  3035.                PUSH   AX                     ;Save failed drive number.
  3036.                MOV    AX,CS
  3037.                MOV    DS,AX                  ;Point to our data segment.
  3038.                MOV    ES,AX
  3039.  
  3040.                CALL   CLEAR_MSG              ;Clear current message.
  3041.                MOV    SI,OFFSET DISK_MSG     ;Display disk error message.
  3042.                MOV    DX,172FH
  3043.                CALL   DISPLAY_TEXT
  3044.                POP    AX                     ;Retrieve fail drive and display.
  3045.                ADD    AL,"A"
  3046.                CALL   WRITE_TEXT
  3047.                MOV    DX,182FH               ;Display rest of error message.
  3048.                CALL   DISPLAY_TEXT
  3049.  
  3050. WAIT_KEY:      CALL   READ_KEY               ;Get a response to message.
  3051.                CMP    AH,K_R                 ;Was it scan code for "R"?
  3052.                JZ     END_DISK               ;If yes retry.
  3053.                CMP    AH,K_Q                 ;Was it "Q"?
  3054.                JNZ    WAIT_KEY               ;If no, wait until correct response
  3055.                JMP    EXIT                   ;Else, exit to DOS.
  3056.  
  3057. END_DISK:      CALL   CLEAR_MSG              ;Clear disk error message.
  3058.                POP    ES                     ;Restore registers.
  3059.                POP    DS
  3060.                POP    BP
  3061.                POP    DI
  3062.                POP    SI
  3063.                POP    DX
  3064.                POP    CX
  3065.                POP    BX
  3066.                POP    AX
  3067.                POPF
  3068.                MOV    AL,1                   ;Return with retry request.
  3069.                IRET
  3070.                                                 ;
  3071.                  PAGE   60,132
  3072.  
  3073.                  ;Usage is: call envsub  ds:si -> length,string
  3074.  
  3075.                  ;      length is 1 byte long, <128
  3076.                  ;         if high bit on, primary environment is set.
  3077.                  ;      string is of form: name=value
  3078.  
  3079.                  ;   Copyright 1987, A. B. Krueger GPW MI 48236
  3080.                  ;   All rights reserved. Contact "ARNY KRUEGER"
  3081.                  ;   at the EXEC-PC BBS (414-964-5160) for permission
  3082.                  ;   to use commercially.
  3083.                  ;
  3084.  
  3085.                  ;Clone of SET command that demonstrates updating
  3086.                  ;      the environment string.
  3087.                  ;If there is no secondary command processor, the
  3088.                  ;      global environment is updated
  3089.                  ;If there is a secondary command processor, then
  3090.                  ;      its enviroment is updated
  3091.  
  3092. sb               segment at 0      ;equates storage blocks and psp's
  3093.  
  3094. sb_kind          db     ' '        ;type of storage block: 'M' or 'Z'
  3095. sb_psp           dw     ?          ;psp segment address
  3096. sb_length        dw     ?          ;sb length in paragraphs
  3097. sb_head_length   equ    10h        ;length of sb header
  3098.                  org    sb_head_length
  3099. sb_data          db     ?          ;data in block
  3100.  
  3101.                  org    0h         ;program segement prefix equates
  3102. psp_ret_int      dw     ?          ;int 20h
  3103.                  org    2Ch
  3104. psp_env          dw     ?          ;segment address of environment
  3105.                  org    50h
  3106. psp_dos_function dw     ?          ;address of function dispatcher
  3107.                  org    80h
  3108. psp_parm_string  db     ?          ;1 byte length plus parm string
  3109.  
  3110. psp_length       equ    100h
  3111.  
  3112. sb               ends
  3113.  
  3114. code_seg         segment para public
  3115.                  assume cs:code_seg,ds:code_seg,es:sb
  3116.                  public env_set
  3117.  
  3118.                  ;local  data
  3119.  
  3120. cr               equ    13
  3121. lf               equ    10
  3122.  
  3123. sb_count         dw    0            ;count of sb's encountered
  3124. sb_shell         dw    0            ;segment address of shell  sb
  3125. sb_shell_env     dw    0            ;segment address of global env sb
  3126. sb_secondary     dw    0            ;segment address of secondary command.com
  3127. sb_secondary_env dw    0            ;segment address of secondary command env
  3128.  
  3129. fatal_msg       equ    80h
  3130. error_msg       equ    40h
  3131. info_msg        equ    20h
  3132. msg_flag        db     fatal_msg+error_msg ;+info_msg   ;set flags
  3133.                 db     'Copyright 1987, A. B. Krueger GPW MI 48236'
  3134. secondary_msg   db     info_msg,'Secondary '
  3135. command_found   db     info_msg,'COMMAND.COM found',cr,lf,'$'
  3136. bad_dos_msg     db     fatal_msg,'Must be running under DOS 2.0 or above',cr,lf,'$'
  3137. bad_sb_msg      db     fatal_msg,'Bad storage block',cr,lf,'$'
  3138. bad_env_msg     db     error_msg,'Bad environment block',cr,lf,'$'
  3139. command_lost    db     error_msg,'Shell never found',cr,lf,'$'
  3140. addbadmsg       db     error_msg,'Environment corrupt',cr,lf,'$'
  3141. addmsg          db     info_msg,'Addition requested',cr,lf,'$'
  3142. removemsg       db     info_msg,'Removal requested',cr,lf,'$'
  3143. env_set_nospace db     error_msg,'No space in environment string',cr,lf,'$'
  3144. env_set_syntax  db     error_msg,'Set string syntax error',cr,lf,'$'
  3145.  
  3146. type_string     proc   near          ;type message at offset in dx
  3147.                 push   ax            ;save registers
  3148.                 push   cx
  3149.                 push   dx
  3150.                 push   si
  3151.  
  3152.                 mov    si,dx         ;get message level
  3153.                 lodsb
  3154.                 and    al,msg_flag   ;compare to what sells
  3155.                 jz     type_ret      ;if not on list, send to bit bucket
  3156.  
  3157.                 mov    dx,si
  3158.                 mov    ax,0900h
  3159.                 int    21h
  3160. type_ret:
  3161.                 pop    si
  3162.                 pop    dx
  3163.                 pop    cx
  3164.                 pop    ax
  3165.                 ret
  3166. type_string     endp
  3167.  
  3168. get_first_sb    proc   near       ;get first storage block, point es at it
  3169.                 push   ax
  3170.                 push   bx
  3171.                 mov    ax,5200h
  3172.                 int    21h        ;es:bx points to memory block anchor+2
  3173.                 dec    bx
  3174.                 dec    bx
  3175.                 mov    es,es:[bx] ;get first memory block address into es
  3176.                 pop    bx
  3177.                 pop    ax
  3178.                 ret
  3179. get_first_sb    endp
  3180.  
  3181. get_next_sb     proc   near
  3182.                 push   ax
  3183.                 mov    ax,es             ;get current paragraph
  3184.                 add    ax,es:sb_length      ;add in number of paragraphs
  3185.                 inc    ax                ;add 1 for header
  3186.                 mov    es,ax             ;set new extra segment address
  3187.                 pop    ax
  3188.                 ret
  3189. get_next_sb     endp
  3190.  
  3191.  
  3192. find_secondary_env proc  near       ;find env sb's for current program sb
  3193.                 push   ax           ;pointed to by es
  3194.                 push   es
  3195.                 mov    ax,es        ;get address of secondary cp's sb
  3196.                 inc    ax           ;get its psp address
  3197. find_secondary_env_loop:
  3198.                 call   get_next_sb  ;get next sb
  3199.                 cmp    ax,es:sb_psp    ;match secondary's psp?
  3200.                 jne    find_secondary_env_next    ;if not, skip
  3201.  
  3202.                 mov    sb_secondary_env,es        ;otherwise, save
  3203.                 jmp    find_secondary_env_exit    ;and check no further
  3204.                                                   ;lest we trash a .BAT block
  3205. find_secondary_env_next:
  3206.                 cmp    es:sb_kind,'Z'                ;last block?
  3207.                 jne    find_secondary_env_loop
  3208.  
  3209. find_secondary_env_exit:
  3210.                 pop    es
  3211.                 pop    ax
  3212.                 ret
  3213. find_secondary_env endp
  3214.  
  3215. command_test    proc   near         ;test program storage block at es:0
  3216.                 push   ax
  3217.                 push   bx
  3218.                 push   cx
  3219.                 push   dx
  3220.                 push   ds
  3221.                 push   es
  3222.                 push   si
  3223.  
  3224.                 cmp    sb_count,2
  3225.                 ja     command_second
  3226.  
  3227.                 mov    dx,offset command_found
  3228.                 call   type_string
  3229.                 mov    sb_shell,es
  3230.                 jmp    command_test_good
  3231.  
  3232. command_second:
  3233.                 cmp    sb_shell,0                       ;did we find shell?
  3234.                 je     command_first_bad                ;if not, error
  3235.  
  3236.                 cmp    word ptr es:psp_env+es:sb_head_length,0  ;check envir of program
  3237.                 je     command_test_good                 ;if no environment, quit
  3238.  
  3239.                 push   sb_shell
  3240.                 pop    ds                               ;ds points to shell
  3241.                 mov    al,byte ptr es:sb_head_length+es:psp_length
  3242.                 cmp    al,0E9h                          ;a JMP?
  3243.                 jne    command_test_good                ;if not, no harm done
  3244.  
  3245.                 cmp    al,byte ptr ds:sb_head_length+es:psp_length  ;check 1st instruction
  3246.                 jne    command_first_bad
  3247.  
  3248.                 mov    si,es:sb_head_length+es:psp_length
  3249.                 mov    di,es:sb_head_length+es:psp_length
  3250.                 mov    cx,10      ;look at 10 words of code
  3251.                 repz   cmpsw
  3252.                 clc
  3253.                 jcxz   command_test_found   ;if they all match, fine
  3254.  
  3255.                 jmp    command_test_good    ;if not, no harm done
  3256.  
  3257. command_test_found:
  3258.                 push   cs
  3259.                 pop    ds
  3260.                 mov    sb_secondary,es
  3261.  
  3262.                 mov    ax,es:psp_env+es:sb_head_length     ;get env address
  3263.                 dec    ax                               ;back up over sb header
  3264.                 mov    sb_secondary_env,ax              ;and save it
  3265.  
  3266.                 call   find_secondary_env               ;look for other env's
  3267.  
  3268.                 mov    dx,offset secondary_msg
  3269.                 call   type_string
  3270.                 jmp    command_test_good
  3271.  
  3272. command_first_bad:
  3273.                 mov    dx,offset command_lost
  3274.                 call   type_string
  3275.                 stc
  3276.                 jmp    command_test_end
  3277.  
  3278. command_test_good:
  3279.                 clc
  3280. command_test_end:
  3281.                 pop    si
  3282.                 pop    es
  3283.                 pop    ds
  3284.                 pop    dx
  3285.                 pop    cx
  3286.                 pop    bx
  3287.                 pop    ax
  3288.  
  3289.                 ret
  3290. command_test    endp
  3291.  
  3292.  
  3293.  
  3294. prog_test       proc   near         ;test block for program
  3295.                 push   ax           ;save registers
  3296.                 push   cx
  3297.                 push   dx
  3298.                 push   es
  3299.  
  3300.                 mov    ax,es:sb_psp             ;get PSP of owner
  3301.                 cmp    ax,0                  ;if zero, it is free
  3302.                 je     prog_exit
  3303.  
  3304.                 cmp    ax,8                  ;if PSP of owner is at 8
  3305.                 je     prog_exit             ;block owned by config.sys
  3306.  
  3307.                 sub    ax,es:sb_head_length     ;get address of sb containg program
  3308.                 cmp    ax,sb_shell           ;is owner the primary shell?
  3309.                 je     prog_exit
  3310.                 push   es
  3311.                 pop    ax
  3312.                 cmp    ax,es:sb_psp             ;compare to address of owner
  3313.                 ja     prog_exit             ;if owner below SB, system-owned
  3314.  
  3315.                 add    ax,es:sb_length          ;add in length
  3316.                 cmp    ax,es:sb_psp             ;compare to owner's PSP
  3317.                 JB     prog_exit             ;if end below owner PSP, no program
  3318.                 cmp    es:sb_length,10          ;is block long enough to have a psp?
  3319.                 jbe    prog_exit             ;if not, no program
  3320.  
  3321.                 mov    ax,word ptr es:psp_dos_function+es:sb_head_length
  3322.                 cmp    ax,word ptr cs:psp_dos_function   ;check PSP validity
  3323.                 jne    prog_exit
  3324.  
  3325.                 mov    ax,word ptr es:psp_ret_int+es:sb_head_length
  3326.                 cmp    ax,word ptr cs:psp_ret_int     ;check PSP validity
  3327.                 jne    prog_exit                ;if invalid, skip looking for env
  3328.  
  3329.                 call   command_test
  3330.                 clc
  3331. prog_exit:
  3332.  
  3333.                 pop    es                       ;restore registers
  3334.                 pop    dx
  3335.                 pop    cx
  3336.                 pop    ax
  3337.                 ret
  3338.  
  3339. prog_test       endp
  3340.  
  3341. sb_scan         proc   near           ;loop cx storage blocks
  3342.  
  3343.                 mov    al,es:sb_kind     ;get storage block type byte
  3344.                 cmp    al,04dh        ;ordinary storage block
  3345.                 je     sb_scan_got
  3346.                 cmp    al,05ah
  3347.                 jne    sb_scan_bad
  3348.                 mov    cx,1           ;last block
  3349.  
  3350. sb_scan_got:
  3351.                 inc    sb_count              ;count storage blocks
  3352.  
  3353.                 cmp    sb_count,3            ;blocks 1 and 2 not global env
  3354.                 jb     sb_scan_not_global
  3355.  
  3356.  
  3357.                 cmp    sb_count,4            ;blocks 5-up not global env
  3358.                 ja     sb_scan_not_global
  3359.  
  3360.                 cmp    sb_shell_env,0        ;do we have an env yet ?
  3361.                 ja     sb_scan_not_global    ; yes, forget this one
  3362.  
  3363.                 cmp    es:sb_data,'!'           ;this block an environment ?
  3364.                 jb     sb_scan_not_global    ; no, obviously not
  3365.  
  3366.                 cmp    es:sb_data,'~'           ;this block an environment ?
  3367.                 ja     sb_scan_not_global    ; no, obviously not
  3368.  
  3369.                 mov    sb_shell_env,es
  3370.                 jmp    sb_scan_get
  3371.  
  3372. sb_scan_not_global:
  3373.                 call   prog_test             ;look for program
  3374.  
  3375.                 loop   sb_scan_get
  3376.                 jmp    sb_scan_end
  3377.  
  3378. sb_scan_get:
  3379.                 call   get_next_sb
  3380.                 jmp    sb_scan
  3381.  
  3382. sb_scan_end:
  3383.                 clc
  3384.                 jmp    sb_scan_exit
  3385.  
  3386. sb_scan_bad:
  3387.                 mov    al,2
  3388.                 mov    dx,offset bad_sb_msg
  3389.                 stc
  3390.  
  3391. sb_scan_exit:
  3392.                 ret
  3393. sb_scan         endp
  3394.  
  3395.  
  3396. sb_anal         proc   near           ;proc to analyze storage blocks
  3397.                                       ; to find environment(s)
  3398.                 push   ax
  3399.                 push   cx
  3400.                 push   dx             ;carry flag = error
  3401.                 push   es             ;error level in al
  3402.                 mov    ah,30h         ;get release number
  3403.                 int    21h
  3404.                 cmp    al,01h         ;above dos 1.x?
  3405.                 jna    sb_bad_dos
  3406.  
  3407.                 cld                  ;clear direction flag
  3408.                 call   get_first_sb
  3409.                 mov    cx,9999        ;scan all blocks
  3410.                 call   sb_scan
  3411.                 jc     sb_send_msg    ;if any errors, exit
  3412.  
  3413.                 jmp    sb_exit
  3414.  
  3415. sb_bad_dos:
  3416.                 mov    al,1
  3417.                 mov    dx,offset bad_dos_msg
  3418.                 stc
  3419.                 jmp    sb_send_msg
  3420.  
  3421. sb_bad_env:
  3422.                 mov    al,3
  3423.                 mov    dx,offset bad_env_msg
  3424.                 stc
  3425. sb_send_msg:
  3426.                 pushf
  3427.                 call   type_string
  3428.                 popf
  3429. sb_exit:
  3430.                 pop    es
  3431.                 pop    dx
  3432.                 pop    cx
  3433.                 pop    ax
  3434.  
  3435.                 ret
  3436. sb_anal         endp
  3437.  
  3438. make_upper     proc    near          ;make cx bytes at es:di upper case
  3439.  
  3440.                push    ax            ;save registers modified
  3441.                push    cx
  3442.                push    di
  3443.                push    ds
  3444.                push    si
  3445.  
  3446.                push    es
  3447.                pop     ds
  3448.                mov     si,di
  3449. make_upper_loop:
  3450.                lodsb                  ;get a byte
  3451.                cmp     al,'a'           ;if lower case:
  3452.                jb      make_upper_next
  3453.                cmp     al,'z'
  3454.                ja      make_upper_next
  3455.                and     al,255-'a'+'A'   ;make upper case
  3456. make_upper_next:
  3457.                stosb                  ;store out results
  3458.                loop    make_upper_loop
  3459.  
  3460.                pop     si            ;restore registers
  3461.                pop     ds
  3462.                pop     di
  3463.                pop     cx
  3464.                pop     ax
  3465.                ret
  3466. make_upper     endp
  3467.  
  3468.  
  3469.  
  3470. env_var_name  proc     near               ;find environment variable name at
  3471.               push     ax                 ;  ds:si, length in cx
  3472.               push     bx                 ;at exit, ds:di points to name
  3473.               push     di                 ;         name length in cx
  3474.               push     es                 ;variable contents length to dx
  3475.  
  3476.               push     cx                 ;save length and pointer
  3477.               push     si                 ;for error exits
  3478.  
  3479.               jcxz     env_var_name_bad   ;if length is 0, exit
  3480.  
  3481.  
  3482.               push     cs                 ;scan works at es:di
  3483.               pop      es
  3484.               mov      di,si
  3485.               mov      al,' '             ;scan for non-blank
  3486.  
  3487. env_var_strip:
  3488.               repz     scasb              ;look for non-blank
  3489.               jcxz     env_var_name_bad   ;if all blank, error!
  3490.  
  3491.               inc      cx                 ;back up over non-blank character
  3492.               dec      di
  3493.               mov      si,di              ;save start of non-blank string
  3494.               mov      bx,cx              ;save length
  3495.  
  3496.               repnz    scasb              ;look for a blank
  3497.               mov      dx,di              ;save location of ' ' or end
  3498.  
  3499.               mov      cx,bx              ;reset search length
  3500.               mov      di,si              ;reset search pointer
  3501.               mov      al,'='             ;search for equals sign
  3502.               repnz    scasb
  3503.               jne      env_var_name_bad   ;if not found, error
  3504.  
  3505.               cmp      di,dx              ;compare location of '=' and ' '
  3506.               ja       env_var_name_bad   ;found ' ' first? then exit
  3507.  
  3508.               mov      dx,bx              ;restore search length
  3509.               add      dx,si              ;add start
  3510.               sub      dx,di              ;subtract where '=' was
  3511.  
  3512.               pop      ax                 ;pop old si from stack
  3513.               pop      ax                 ;pop old cx from stack
  3514.  
  3515.               mov      cx,di              ;where we found '='
  3516.               sub      cx,si              ;subtract string start
  3517.               dec      cx                 ;minus 1 for '='
  3518.               clc                         ;all is well
  3519.               jmp      env_var_name_exit
  3520.  
  3521. env_var_name_bad:
  3522.               pop      si                 ;restore pointer and length
  3523.               pop      cx
  3524.               xor      dx,dx              ;contents length assumed zero
  3525.               stc                         ;problems  - set carry
  3526.  
  3527. env_var_name_exit:
  3528.               pop      es
  3529.               pop      di
  3530.               pop      bx                 ;restore registers
  3531.               pop      ax
  3532.               ret
  3533.  
  3534. env_var_name  endp
  3535.  
  3536. get_sb_size   proc     near              ;get byte size of sb at es:0 in cx
  3537.               push     ax
  3538.               mov      ax,es:sb_length      ;get length of env in paragraphs
  3539.               mov      cl,4              ;times 16
  3540.               shl      ax,cl
  3541.               mov      cx,ax
  3542.               pop      ax
  3543.               ret
  3544. get_sb_size   endp
  3545.  
  3546. env_var_find  proc     near              ;find environment variable
  3547.                                          ;named in ds:si,name length in cx
  3548.                                          ;return string start in es:di
  3549.                                          ;length of entire string in cx
  3550.               push     ax                ;save registers
  3551.               push     bx
  3552.               push     dx
  3553.  
  3554.               mov      bx,cx             ;save length of name
  3555.               push     es                ;save env block address
  3556.               push     ds                ;set  es:di to source string
  3557.               pop      es                ;     "
  3558.               mov      di,si             ;make name upper case
  3559.               call     make_upper        ;altering input string
  3560.               pop      es                ;restore es to environment block
  3561.  
  3562.               call     get_sb_size       ;get size of sb in bytes
  3563.  
  3564.               mov      di,es:sb_head_length ;start at data portion of block
  3565.               mov      dx,cx             ;save block length
  3566.  
  3567. env_var_find_loop:
  3568.               push     si                ;save string pointers
  3569.               push     di
  3570.  
  3571.               mov      cx,bx             ;compare for length of name
  3572.               mov      ah,1              ;say not compare
  3573.               repz     cmpsb             ;compare item to name for name length
  3574.               jne      env_var_find_next ;if not found, scan on
  3575.  
  3576.               cmp      byte ptr es:[di],'='   ;check next byte for '='
  3577.               jne      env_var_find_next ;if found, go calc length
  3578.  
  3579.               mov      ah,0              ;say compare ok
  3580. env_var_find_next:
  3581.               pop      di                ;restore string pointers
  3582.               pop      si
  3583.  
  3584.               xor      al,al             ;look for end of current substring
  3585.               mov      cx,dx             ;search remainder of string
  3586.               mov      dx,di             ;save search start
  3587.               repnz    scasb             ;search for a zero
  3588.               jne      env_var_find_end  ;none found, error
  3589.  
  3590.               cmp      ah,0              ;did original compare fly?
  3591.               je       env_var_find_found;if so, then pass length, etc
  3592.  
  3593.               cmp      byte ptr es:[di],0  ;check next byte for zero
  3594.               je       env_var_find_end  ;if found, name not found
  3595.  
  3596.               mov      dx,cx             ;save length of string remaining
  3597.               jmp      env_var_find_loop ;and loop on
  3598.  
  3599. env_var_find_end:
  3600.               xor      cx,cx             ;length = 0, none found
  3601.               stc                        ;set error flag
  3602.               jmp      env_var_find_exit
  3603.  
  3604. env_var_find_found:
  3605.               mov      cx,di             ;save count of end of string
  3606.               mov      di,dx             ;restore search start
  3607.               sub      cx,di             ;calc length of search
  3608.               dec      cx                ;less length of zero
  3609.               clc                        ;no errors
  3610.  
  3611. env_var_find_exit:
  3612.               pop      dx
  3613.               pop      bx                ;restore registers
  3614.               pop      ax
  3615.               ret
  3616. env_var_find  endp
  3617.  
  3618.  
  3619. null_var      dw       -1
  3620.  
  3621. env_var_add   proc near                     ;add  environment variable
  3622.                                             ;expression ->ds:si, length in cx
  3623.               push    ax                    ;save registers
  3624.               push    bx
  3625.               push    dx
  3626.  
  3627.               mov     dx,offset addmsg
  3628.               call    type_string
  3629.               mov     bx,cx
  3630.               push    si
  3631.               mov     si,offset null_var  ;send on wild goose chase
  3632.               mov     cx,2                ;looking for  x'ffff'
  3633.               call    env_var_find        ;es:di points to end of env
  3634.               pop     si
  3635.               jnc     env_var_add_env_bad
  3636.                                           ;es:di now points to end of env
  3637.               call    get_sb_size         ;get length of env area in cx
  3638.               add     cx,es:sb_head_length   ;add head length for offsets
  3639.               sub     cx,bx               ;deduct length of string
  3640.               sub     cx,2                ;deduct length of flag
  3641.               cmp     di,cx               ;compare to where we add
  3642.               ja      env_var_add_bad     ;if no space, too bad
  3643.  
  3644.               mov     cx,bx               ;length of string to add
  3645.               rep     movsb               ;do the deed
  3646.               xor     ax,ax               ;make flag of two zeros
  3647.               stosw                       ;add is on
  3648.  
  3649.               jmp     env_var_add_good
  3650.  
  3651. env_var_add_env_bad:
  3652.               mov     dx,offset addbadmsg
  3653.               call    type_string
  3654.  
  3655. env_var_add_bad:
  3656.               stc
  3657.               jmp     env_var_add_exit
  3658.  
  3659. env_var_add_good:
  3660.               clc
  3661. env_var_add_exit:
  3662.               pop     dx                  ;restore registers
  3663.               pop     bx
  3664.               pop     ax
  3665.               ret
  3666.  
  3667. env_var_add   endp
  3668.  
  3669.  
  3670. env_var_remove proc near                ;remove environment variable
  3671.                                         ;at es:di, length in cx
  3672.               push    cx
  3673.               push    dx
  3674.               push    ds
  3675.               push    di
  3676.               push    si
  3677.  
  3678.               cld                      ;move left to right
  3679.  
  3680.               mov     dx,offset removemsg
  3681.               call    type_string
  3682.  
  3683.               inc     cx                  ;add 1 for zero byte
  3684.               mov     dx,cx               ;save length of var
  3685.               call    get_sb_size         ;cx gets length of env area
  3686.               add     cx,es:sb_head_length   ;add header length for offsets
  3687.               sub     cx,di               ;deduct where we start
  3688.               sub     cx,dx               ;deduct length of removed variable
  3689.  
  3690.               mov     si,di               ;move from next variable
  3691.               add     si,dx               ;add my length
  3692.  
  3693.               push    es                  ;do all the work in es:
  3694.               pop     ds
  3695.  
  3696.               rep     movsb               ;do the move
  3697.  
  3698.               pop     si
  3699.               pop     di
  3700.               pop     ds
  3701.               pop     dx
  3702.               pop     cx
  3703.               ret
  3704. env_var_remove  endp
  3705.  
  3706.  
  3707. env_set       proc    near                ;change environment per ds:si
  3708.               push    ax
  3709.               push    bx                  ;ds:si points to:
  3710.               push    cx                  ; length  db  ?
  3711.               push    di
  3712.               push    ds                  ; data    db  'name=value'
  3713.               push    es
  3714.               push    si
  3715.               mov sb_count,0              ;count of sb's encountered
  3716.               mov sb_shell,0              ;segment address of shell  sb
  3717.               mov sb_shell_env,0          ;segment address of global env sb
  3718.               mov sb_secondary,0          ;segment address of secondary command.com
  3719.               mov sb_secondary_env,0      ;segment address of secondary command env
  3720.  
  3721.               xor     ax,ax               ;set length of local set string
  3722.               lodsb                       ;get length, push di forward
  3723.               mov     cx,ax               ;length of set string in cx
  3724.               and     cl,0ffh-80h         ;length < 128
  3725.               call    sb_anal             ;analyze the storage block chain
  3726.                                           ;to find command processor(s)
  3727.  
  3728.               and     al,80h              ;was use primary switch on?
  3729.               jnz     env_set_shell       ;if so, skip secondaries
  3730.  
  3731.               cmp     sb_secondary_env,0  ;is there a secondary command proc?
  3732.               je      env_set_shell       ;if not, use primary
  3733.  
  3734.               mov     es,sb_secondary_env ;command processor is secondary
  3735.               jmp     env_set_command
  3736.  
  3737. env_set_shell:                            ;command processor is shell
  3738.               mov     es,sb_shell_env
  3739. env_set_command:
  3740.               call    env_var_name        ;find what we want set at call
  3741.                                           ;ds:si -> expression, cx has length
  3742.                                           ;at return ds:si -> name
  3743.                                           ;cx is length of name
  3744.               jc      env_set_syntax_err  ;if not found, error
  3745.  
  3746.               mov     bx,cx               ;calculate new length of set string
  3747.               inc     bx                  ;add 1 for '='
  3748.               add     bx,dx               ;add length of set string
  3749.  
  3750.               call    env_var_find        ;find variable in environment block
  3751.                                           ;at return, es:di -> start of env str
  3752.                                           ;cx is length of env str
  3753.               jc      env_set_add         ;if not found, just add
  3754.  
  3755.               call    env_var_remove      ;remove variable at es:di from env
  3756.               cmp     dx,0                ;check out length of data to add
  3757.               je      env_set_exit        ;if zero, just exit
  3758.  
  3759. env_set_add:
  3760.               mov     cx,bx               ;restore length of variable
  3761.               call    env_var_add         ;add new variable to set string
  3762.               jc      env_set_no_space
  3763.               jmp     env_set_exit
  3764.  
  3765. env_set_no_space:
  3766.               mov     dx,offset env_set_nospace
  3767.               jmp     env_set_type
  3768.  
  3769. env_set_syntax_err:
  3770.               mov     dx,offset env_set_syntax
  3771. env_set_type:
  3772.               push    cs
  3773.               pop     ds
  3774.               call    type_string
  3775. env_set_error:
  3776.               stc
  3777. env_set_exit:
  3778.               pop     si
  3779.               pop     es
  3780.               pop     ds
  3781.               pop     di
  3782.               pop     cx
  3783.               pop     bx
  3784.               pop     ax
  3785.               ret
  3786. env_set       endp
  3787.  
  3788. code_seg      ends
  3789.               end
  3790.  
  3791. 
  3792. CURRENT_DIR    DB     0                         ;
  3793. WORKING_DIR    EQU    CURRENT_DIR+68            ;
  3794. PURGE_DIR      EQU    CURRENT_DIR+136
  3795. SOURCE         EQU    CURRENT_DIR+202
  3796. TARGET         EQU    CURRENT_DIR+280          ;
  3797. ENTRY          EQU    CURRENT_DIR+358
  3798. BUFFER         EQU    CURRENT_DIR+394          ;
  3799.  
  3800. ;
  3801. ;
  3802. ;
  3803. CODE ENDS
  3804. END START
  3805.